- Swift的字符串类型String,跟OC的NSString,在API设计上还是有较大差异
//空字符串
var emptyStr1 = ""
var emptyStr2 = String()
var str1: String = "1"
str1.append("_2") //"1_2"
str1 = str1 + "_3" //"1_2_3"
str1 += "_4" //"1_2_3_4"
str1 = "\(str1)_5" //"1_2_3_4_5"
print(str1.count) //9
var str2 = "123456"
print(str2.hasPrefix("123")) //true
print(str2.hasSuffix("456")) //true
String的插入和删除
var str = "1_2"
str.insert("_", at: str.endIndex) //这种方法只能插入一个字符 "1_2_"
str.insert(contentsOf: "3_4", at: str.endIndex) //这种方法能插入字符串 "1_2_3_4"
str.insert(contentsOf: "666", at: str.index(after: str.startIndex)) //"1666_2_3_4"
str.insert(contentsOf: "888", at: str.index(before: str.endIndex)) //"1666_2_3_8884"
str.insert(contentsOf: "hello", at: str.index(str.startIndex, offsetBy: 4)) //"1666hello_2_3_8884"
str.remove(at: str.firstIndex(of: "1")!) //"666hello_2_3_8884"
str.removeAll {$0 == "6"} //"hello_2_3_8884"
var range = str.index(str.endIndex, offsetBy: -4)..<str.index(before: str.endIndex)
str.removeSubrange(range) //"hello_2_3_4"
Substring
- String可以通过下标、prefix、suffix等截取子串,子串类型不是String,而是Substring
- Substring和它的base,共享字符串数据
- Substring发生修改转为String 时,会重新分配新的内存存储字符串数据
var str = "1_2_3_4"
var substr1 = str.prefix(3) //"1_2"
var substr2 = str.suffix(3) //"3_4"
var range = str.startIndex..<str.index(str.startIndex, offsetBy: 3)
var substr3 = str[range] //"1_2" //substr3和str共同占用一块内存,只是substr3指向所截取的字符串,但是当substr3发生拼接等改变时,就会开辟新的内存来存储,不在与str公用一块内存
var range1 = str.index(str.startIndex, offsetBy: 2)..<str.index(str.startIndex, offsetBy: 4)
var substr4 = str[range1] //"2_"
print(type(of: substr3)) //Substring
print(substr3.base) //.base表示最初的String:1_2_3_4
var str2 = String(substr3) //Substring -> String //此时当substr3转化为String类型,会重新开辟新的内存,将str2放到新的内存
对于上面代码substr3和str的内存解释如图:
String与Character
for ch in "Jack" {
print(type(of: ch)) //ch是Character类型,不是String类型
print(ch)
}
var str = "Jack"
var c = str[str.startIndex] // "K"
print(type(of: c)) //c是character类型
String相关的协议
- BidirectionalCollection 协议包含的部分内容
- startIndex 、 endIndex 属性、index 方法
- String、Array 都遵守了这个协议
- RangeReplaceableCollection 协议包含的部分内容
- append、insert、remove 方法
- pString、Array 都遵守了这个协议
- Dictionary、Set 也有实现上述协议中声明的一些方法,只是并没有遵守上述协议
String与NSString
- String 与 NSString 之间可以随时随地桥接转换
- 如果你觉得String的API过于复杂难用,可以考虑将String转为NSString
var str1: String = "Jack"
var str2: NSString = "rose"
var str3 = str1 as NSString
var str4 = str2 as String
//swift和OC上面的相互转换是要调用相应函数的,是有一定开销的,
var str5 = str3.substring(with: NSRange(location: 0, length: 2)) //str3可以直接调用oc里的NSRange等相应方法
print(str5) //"Ja"
通过反汇编,我们可以看出swift的String转化为NSString的底层调用:
由上图可以看出,swift通过桥接oc来调用相应的函数。
多行String
多行String用
"""
"""
来标记,并且根据下面的"""的最左边来截取字符串
let str = """
1
"2"
3
"4"
"""
print(str)
//输出结果
//1
// "2"
//3
// "4"
let str1 = """
1
2
3
4
"""
print(str1)
//输出结果
//1
// 2
// 3
// 4
//这里可以看出根据下面"""的最左边来截取字符串,所以1的前面没空格
String与NSString
- String 与 NSString 之间可以随时随地桥接转换
- 如果你觉得String的API过于复杂难用,可以考虑将String转为NSString
var str1: String = "Jack"
var str2: NSString = "rose"
var str3 = str1 as NSString
var str4 = str2 as String
//swift和OC上面的相互转换是要调用相应函数的,是有一定开销的,
var str5 = str3.substring(with: NSRange(location: 0, length: 2)) //str3可以直接调用oc里的NSRange等相应方法
print(str5) //"Ja"
下面是swift的String转化为NSString的底层汇编代码(var str3 = str1 as NSString),可以看到是调用了桥接等函数的。
- 比较字符串内容是否等价
- String使用 == 运算符
- NSString使用isEqual方法,也可以使用 == 运算符(本质还是调用了isEqual方法,底层走了objc_msgSend)
var str1: String = "Jack"
var str11: String = "Jack"
var str2: NSString = "rose"
var str22: NSString = "rose"
print(str1 == str11) //true
print(str2 == str22) //true
Swift、OC桥接转换表
- OC的不可变类型可以与Swift的相应类型互相转换
- OC的可变类型不可以与Swift的相应类型互相转换,只可以单方向转换为Swift的对应类型
//String与NSString可以互相桥接转换
//String不能使用as等直接桥接转换成NSMutableString,NSMutableString能桥接转换成String
var str1: String = "jack"
var str2: NSString = "Alan"
var str3: NSMutableString = "Anna"
var str4 = str1 as NSString
var str5 = str2 as String
var str6 = str3 as String
String不能使用as等直接桥接转换成NSMutableString,但是可以通过创建一个全新的NSMutableString对象来将String转化为NSMutableString,代码如下:
var str = "123456"
var str2 = NSMutableString(string: str)
print(str2) // "123456" NSMutableString
Swift中class Woman和class Woman: NSObject的内存结构
- class Woman:
class Woman {
var age = 10
var weight = 20
}
var p = Woman()
print(Mems.memStr(ofRef: p))
//内存结构
//0x0000000109cc8400 metadata
//0x0000000200000002 引用计数
//0x000000000000000a age:10
//0x0000000000000014 wight:20
- class Woman: NSObject:
class Woman: NSObject {
var age = 10
var weight = 20
}
var p = Woman()
print(Mems.memStr(ofRef: p))
//内存结构
//0x000000010ec390b0 isa指针
//0x000000000000000a age: 10
//0x0000000000000014 weight: 20
//0x0000000000000000 补位