最近使用swift写新项目,也算是试水,虽然现在swift算是推广起来了,很多大厂小公司的新项目都是swift,但是还是不少坑,这两天写一个waveView就遇到了个这个问题
一般再OC中使用runtime给分类添加属性是这个样子的objc_setAssociatedObject
和objc_getAssociatedObject
1 | - (void)setSomeProperty:(NSString *)someProperty{ |
看了看之前写过的OC代码,微微一笑,写出了这段代码
1 | var refreshView : WaveView{ |
然后用了一下这个这几行检验一下,果然没存进去。。。
我们看一下objc_setAssociatedObject
的API1
2
3
4
5
6
7
8
9
10
11
12
13/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
@available(iOS 3.1, *)
public func objc_setAssociatedObject(_ object: Any!, _ key: UnsafeRawPointer!, _ value: Any!, _ policy: objc_AssociationPolicy)
第二个参数是UnsafeRawPointer
结构体指针类型,Swift并不推荐对指针进行直接操作, 但仍提供了几种可以直接操作内存的指针类型,在Swift中无类型的指针,原始内存可以用UnsafeRawPointer
和UnsafeMutableRawPointer
来表示
我们看一下UnsafeRawPointer
的构造函数
1 | /// Converts a pattern of bits to an `UnsafeRawPointer`. |
要想通过字符串生成意义对应的Int
值,我们可以使用
"key".hashValue
的形式将字符串生成哈希值来返回Int
值1
2
3
4
5
6
7
8
9
10var refreshView : WaveView? {
set{
let key: UnsafeRawPointer! = UnsafeRawPointer(bitPattern: "key".hashValue)
objc_setAssociatedObject(self, key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
get{
let key: UnsafeRawPointer! = UnsafeRawPointer(bitPattern: "key".hashValue)
return objc_getAssociatedObject(self, key) as? WaveView
}
}
这种方法完美解决了解包失败
因为是经常使用的key
值,我们应该一次定义多次调用,避免这样重复写好多次,如同在配置文件里面定义全局通知的标识符一样1
let key = UnsafeRawPointer(bitPattern: "key".hashValue)