** 浅谈 CFArray In Swift **
Access low-level functions, primitive data types, and various collection types that are bridged seamlessly with the Foundation framework.
意思是他是一套底层的API,拥有原始的数据类型,各种与Foundation无缝结合的全集
首先我们来回顾一下Objective-C中CFArray的简单使用
//创建一个CFArray对象
CFMutableArrayRef arr = CFArrayCreateMutable(CFAllocatorGetDefault(), 0, NULL) ;
NSString *name = @"007" ;
NSString *sex = @"男" ;
//向数组添加数据
CFArrayAppendValue(arr, (__bridge void *)name) ;
CFArrayAppendValue(arr, (__bridge void *)sex) ;
//从数据获取数据,并转化成NSString *
NSString *result = (__bridge NSString *) CFArrayGetValueAtIndex(arr, 0) ;
NSLog(@"%@",result) ;
CFRelease(arr) ;
Objective-C已经轻车熟路了,那么在Swift中应该怎么使用呢?
let defaultAllocator = CFAllocatorGetDefault().takeUnretainedValue()
let arr = CFArrayCreateMutable(defaultAllocator, 0, nil)
let name: NSString = "007"
let sex: NSString = "男"
CFArrayAppendValue(arr, Unmanaged.passRetained(name).autorelease().toOpaque())
CFArrayAppendValue(arr, Unmanaged.passRetained(sex).autorelease().toOpaque())
let result = Unmanaged<NSString>.fromOpaque(CFArrayGetValueAtIndex(arr, 0)).takeUnretainedValue()
print(result)
Swift的使用已经有很大不同了(Unmanged的用法请参考:https://www.jianshu.com/p/624706ac006a)
1.CFArray中必须保存的是class,不能是struct
2.CFArrayCreateMutable得到的是一个托管对象,所以我们不需要再使用CFRelease来释放它了
3.CFAllocatorGetDefault()得到的是一个非托管的对象
4.CFArrayAppendValue添加的也是一个非托管对象的指针
接下来我们看看CFArray另一个获取数据的方法CFArrayGetValues
NSString *names[2] = { NULL } ;
CFArrayGetValues(arr, CFRangeMake(0, 2), (void *)&names) ;
for (NSInteger i = 0 ; i < 2 ; i ++) {
NSLog(@"i -> %@",names[i]) ;
}
CFArrayGetValues可以获取到一个范围的值,获取到的数据Objective-C是直接保存到一个数组中
那在Swift中又是怎么使用的呢?
let namesPoint = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0)
CFArrayGetValues(arr, CFRange(location: 0, length: 2), namesPoint)
let buffer = UnsafeMutableBufferPointer<UnsafeRawPointer?>.init(start: namesPoint, count: 2)
buffer.forEach {
if let p = $0 {
print(Unmanaged<NSString>.fromOpaque(p).takeUnretainedValue())
}
}
swift里CFArrayGetValues获取到的是一个指向了一个数组的指针
通过这个指针我们可以创建一个Buffer指针(Swift里Buffer可理解为一个数组的指针)
遍历这个Buffer集合可以得到一个UnsafeRawPointer,这实际就是一个非托管对象的指针,
Unmanaged<NSString>.fromOpaque()方法得到一个非托管对象,然后通过takeUnretainedValue()拿到它的值。
以上就是CFArray在OC与Swift中简单使用的区别,也是最核心的差别。
网友评论