在 NSString 中,有一个length 属性,在 NSMutableAttributedString 设置属性的时候, range 指定的 length 需要和 NSString 的 length 一致,否则就会出现越界错误而导致崩溃。
在 Swift 中使用的是 String 而不是 NSString ,而且 String 是全新设计的类型,虽然可以和 NSString 桥接互相使用,但是 String 的 count 属性却和 NSString 的 length 完全不同,如果在 Swift 里面操作 NSAttributedString 的时候,对于 range 的 length 设置,使用的是 count ,就会造成错误。
正确的做法有两种:
方法一,桥接到 NSString 使用 length 属性:
let string = "OK👌"
let range = NSRange(location: 0, length: (string as NSString).length)
方法二,按 Swift 官方文档的建议,NSString 是以 UTF-16 编码存储字符串的,所应该传 UTF-16 编码的 count 作为 length:
let string = "OK👌"
let range = NSRange(location: 0, length: string.utf16.count)
Note Swift’s String type is bridged with Foundation’s NSString class. Foundation also extends String to expose methods defined by NSString. This means, if you import Foundation, you can access those NSString methods on String without casting. For more information about using String with Foundation and Cocoa, see Bridging Between String and NSString.
