内容简介:For more, please visit my GitHub repo:为了方便下述 Demo,这里定义一个 Pencil 类,并会使用在 Swift 中,当创建一个数组时,数组本身对于添加进去的对象元素默认是强引用(Strong),会使得其引用计数自增。
For more, please visit my GitHub repo: github.com/kingcos/Per…
Date | Notes | Swift | Xcode |
---|---|---|---|
2018-03-15 | 更新部分表述,并将题目扩展至集合类型 | 4.0 | 9.2 |
2018-03-08 | 首次提交 | 4.0 | 9.2 |
Preface
为了方便下述 Demo,这里定义一个 Pencil 类,并会使用 func CFGetRetainCount(_ cf: CoreFoundation.CFTypeRef!) -> CFIndex
方法,即传入一个 CFTypeRef
类型的对象即可获取其引用计数。什么是 CFTypeRef
?查阅官方文档即可得知 typealias CFTypeRef = AnyObject
,所以 CFTypeRef
其实就是 AnyObject
。而 AnyObject
又是所有类隐含遵守的协议。
class Pencil { var type: String var price: Double init(_ type: String, _ price: Double) { self.type = type self.price = price } } CFGetRetainCount(Pencil("2B", 1.0) as CFTypeRef) // 1 let pencil2B = Pencil("2B", 1.0) let pencilHB = Pencil("HB", 2.0) CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 2 2 复制代码
What
在 Swift 中,当创建一个数组时,数组本身对于添加进去的对象元素默认是强引用(Strong),会使得其引用计数自增。
let pencilBox = [pencil2B, pencilHB] CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 3 3 复制代码
那么今天的问题即是,如何使得数组本身对数组元素进行弱引用?
How
WeakBox
final class WeakBox<A: AnyObject> { weak var unbox: A? init(_ value: A) { unbox = value } } struct WeakArray<Element: AnyObject> { private var items: [WeakBox<Element>] = [] init(_ elements: [Element]) { items = elements.map { WeakBox($0) } } } extension WeakArray: Collection { var startIndex: Int { return items.startIndex } var endIndex: Int { return items.endIndex } subscript(_ index: Int) -> Element? { return items[index].unbox } func index(after idx: Int) -> Int { return items.index(after: idx) } } 复制代码
定义好一个可以将所有类型的对象转化为弱引用的类,再通过构建好的新类型,将每个强引用元素转换为弱引用元素。利用 Extension,还可以遵守协议,扩展一些集合方法。
let weakPencilBox1 = WeakArray([pencil2B, pencilHB]) CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 3 3 let firstElement = weakPencilBox1.filter { $0 != nil }.first firstElement!!.type // 2B CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 4 3 Note: 这里的 4 是因为 firstElement 持有(Retain)了 pencil2B,导致其引用计数增 1 复制代码
NSPointerArray
let weakPencilBox2 = NSPointerArray.weakObjects() let pencil2BPoiter = Unmanaged.passUnretained(pencil2B).toOpaque() let pencilHBPoiter = Unmanaged.passUnretained(pencilHB).toOpaque() CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 4 3 weakPencilBox2.addPointer(pencil2BPoiter) weakPencilBox2.addPointer(pencilHBPoiter) CFGetRetainCount(pencil2B as CFTypeRef) CFGetRetainCount(pencilHB as CFTypeRef) // 4 3 复制代码
A collection similar to an array, but with a broader range of available memory semantics.
即 NSPointerArray
比普通的 NSArray
多了一层内存语义。可以更方便的控制其中元素的引用关系,但少了 Swift 中着重强调的类型安全,所以更推荐第一种做法。
Extension
其实不只是数组,集合类型的数据结构对其中的元素默认均是强引用。所以为了更加方便地自定义内存管理方式,Objective-C/Swift 中均有普通类型的对应。但在目前的 Swift 中, NSHashTable
和 NSMapTable
均需要指定类型,更加的类型安全(在网上的过时资料中可以看出,之前的 Swift 也没有规定需指定类型),而在 Objective-C 中只要满足 id
类型即可。
-
NSHashTable
:
// NSHashTable - NSSet let weakPencilSet = NSHashTable<Pencil>(options: .weakMemory) weakPencilSet.add(pencil2B) weakPencilSet.add(pencilHB) 复制代码
-
NSMapTable
:
// NSMapTable - NSDictionary class Eraser { var type: String init(_ type: String) { self.type = type } } let weakPencilDict = NSMapTable<Eraser, Pencil>(keyOptions: .strongMemory, valueOptions: .weakMemory) let paintingEraser = Eraser("Painting") weakPencilDict.setObject(pencil2B, forKey: paintingEraser) 复制代码
- Objective-C:
NSHashTable *set = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; [set addObject:@"Test"]; [set addObject:@12]; 复制代码
也欢迎您关注我的微博@萌面大道V
Reference
以上所述就是小编给大家介绍的《Practice - 在 Swift 中对集合类型元素的弱引用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 读 Zepto 源码之集合元素查找
- 读 Zepto 源码之集合元素查找
- 图解集合 5 :不正确地使用HashMap引发死循环及元素丢失
- CSS 基础:块级元素、行内元素、替换元素、非替换元素
- CSS 技巧篇(六):display设置元素为行内元素时,元素之间存在间隙问题
- 探究行内元素和块级元素
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
社交网站界面设计
Christian Crumlish、Erin Malone / 樊旺斌、师蓉 / 机械工业出版社 / 2010-9-1 / 69.00元
《社交网站界面设计》提供100多种模式、原则以及最佳实践,并针对在设计社交网站时经常遇到的问题给出明确建议。本书将提供给你培养用户交互习惯和构建社区最具价值的参考。 本书作者将与你分享难得的经验,教会你平衡各种不同的因素,并与你的用户共同构建和谐健康的网络社区。 本书教会你 掌握创建任何网站时都会用到的原则 学习基本设计模式,以便向现有的网站中添加新的社交组件 学会在......一起来看看 《社交网站界面设计》 这本书的介绍吧!