Swift学习: String,Swift与OC的桥接

  • 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 协议包含的部分内容 
  1. startIndex 、 endIndex 属性、index 方法
  2. String、Array 都遵守了这个协议
  • RangeReplaceableCollection 协议包含的部分内容
  1. append、insert、remove 方法
  2. 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),可以看到是调用了桥接等函数的。

 

  • 比较字符串内容是否等价
  1. String使用 == 运算符
  2. 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 补位

猜你喜欢

转载自blog.csdn.net/weixin_42433480/article/details/98892198