I've been doing some investigations around the immutability of Swift strings that originate from bridged NSString
, and NSMutableString
and NSTextStorage
in particular. My goal is to have a Swift string that is safe to read concurrently from multiple threads.
let string = NSMutableString(string: "hello")
let swiftString = string as String
string.append(" goodbye")
print(swiftString)
The documentation isn't extremely clear on how this particular situation is handled.
Bridging Between String and NSString
Any String instance can be bridged to NSString using the type-cast operator (as), and any String instance that originates in Objective-C may use an NSString instance as its storage. Because any arbitrary subclass of NSString can become a String instance, there are no guarantees about representation or efficiency when a String instance is backed by NSString storage. Because NSString is immutable, it is just as though the storage was shared by a copy. The first in any sequence of mutating operations causes elements to be copied into unique, contiguous storage which may cost O(n) time and space, where n is the length of the string’s encoded representation (or more, if the underlying NSString has unusual performance characteristics).
While NSString
instances are immutable, NSMutableString
is a subclass of NSString
. Based on my reading here, I wasn't actually sure what was going to happen. But, all seems to work as I would hope. Once I get a Swift string, it becomes immutable, even if it was created as a cast from an NSMutableString
, or from an NSString
which itself is actually an NSMutableString
instance.
Am I correct that an immutable copy is made when the as
cast happens?