ult*_*ous 21 weak-references objective-c objective-c-runtime
我知道OBJC_ASSOCIATION_ASSIGN存在,但是如果目标对象被释放,它是否会将引用归零?或者它是否像旧时代那样需要获取nil-ed或者我们以后会冒错误访问?
0xc*_*ced 33
正如超级神奇所证明的那样,OBJC_ASSOCIATION_ASSIGN不会将弱引用归零,并且您有可能访问已解除分配的对象.但是你自己很容易实现.你只需要一个简单的类来包装一个弱引用的对象:
@interface WeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id object;
@end
@implementation WeakObjectContainer
- (instancetype) initWithObject:(id)object
{
if (!(self = [super init]))
return nil;
_object = object;
return self;
}
@end
Run Code Online (Sandbox Code Playgroud)
然后你必须将WeakObjectContaineras 关联为OBJC_ASSOCIATION_RETAIN(_NONATOMIC):
objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainer alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Run Code Online (Sandbox Code Playgroud)
并使用该object属性访问它以获得归零弱引用:
id object = [objc_getAssociatedObject(self, &MyKey) object];
Run Code Online (Sandbox Code Playgroud)
Vad*_*dim 10
还有一个选项类似于WeakObjectContainer:
- (id)weakObject {
id (^block)() = objc_getAssociatedObject(self, @selector(weakObject));
return (block ? block() : nil);
}
- (void)setWeakObject:(id)object {
id __weak weakObject = object;
id (^block)() = ^{ return weakObject; };
objc_setAssociatedObject(self, @selector(weakObject),
block, OBJC_ASSOCIATION_COPY);
}
Run Code Online (Sandbox Code Playgroud)
尝试过后,答案是否定的。
我在 iOS 6 模拟器下运行了以下代码,但它可能与运行时的先前迭代具有相同的行为:
NSObject *test1 = [NSObject new];
NSObject __weak *test2 = test1;
objc_setAssociatedObject(self, "test", test1, OBJC_ASSOCIATION_ASSIGN);
test1 = nil;
id test3 = objc_getAssociatedObject(self, "test");
Run Code Online (Sandbox Code Playgroud)
最后,test1和test2都是nil,test3是之前存储在test1中的指针。使用 test3 将导致尝试访问已被释放的对象。
| 归档时间: |
|
| 查看次数: |
5249 次 |
| 最近记录: |