【问题标题】:Why weak property of associated object is not nilled out if I call its getter?如果我调用它的getter,为什么关联对象的弱属性不会被取消?
【发布时间】:2020-04-30 18:57:47
【问题描述】:

虽然2020年我还在问关于ObjC的问题有点傻,但请耐心和体谅...

我正在阅读 BloksKit 的源代码,遇到了一个奇怪的情况。

#import <objc/runtime.h>

@interface _WeakAssociatedObjectWrapper : NSObject
@property (nonatomic, weak) id object;
@end

@implementation _WeakAssociatedObjectWrapper
@end

@interface NSObject (AddWeak)
@end

@implementation NSObject (AddWeak)
- (void)setWeakProp:(id)weakProp {
    _WeakAssociatedObjectWrapper *wrapper  = objc_getAssociatedObject(self, @selector(weakProp));
    if (!wrapper) {
        wrapper = [[_WeakAssociatedObjectWrapper alloc] init];
        objc_setAssociatedObject(self, @selector(weakProp), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    wrapper.object = weakProp;
}
- (id)weakProp {
    id value = objc_getAssociatedObject(self, _cmd);
    if ([value isKindOfClass:_WeakAssociatedObjectWrapper.class]) {
        return [(_WeakAssociatedObjectWrapper *)value object];
    }
    return value;
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *obj = [[NSObject alloc] init];
        {
            NSObject *prop = [[NSObject alloc] init];
            [obj setWeakProp:prop];

            [obj weakProp]; // *Weird!!
        }
        NSLog(@"Now obj.weakProp = %@", [obj weakProp]);
    }
    return 0;
}

此代码正在为类别添加一个弱关联对象。(BlocksKit 这样做)

注意*Weird!! 行。如果此行被注释掉,那么它会打印(null),这是合理的,因为prop{} 范围之外被释放。另一方面,如果没有注释掉,它会打印出&lt;NSObject: 0xxxxx&gt;,这表明prop 以某种方式被某人保留(或任何其他原因?)。 这里发生了什么??! (BlocksKit 的行为相同!)

环境:XCode 10.3

【问题讨论】:

    标签: objective-c weak associated-object


    【解决方案1】:

    这是一项功能。对于案件(以及任何类似案件)

    [obj 弱属性];

    按属性/访问器命名约定 ARC 返回 autoreleased 实例,因此在您的情况下 @autoreleasepool 持有它,下面的测试可以显示这一点。

    int main(int argc, const char * argv[]) {
        NSObject *obj = [[NSObject alloc] init];
        @autoreleasepool {
            {
                NSObject *prop = [[NSObject alloc] init];
                [obj setWeakProp:prop];
    
                [obj weakProp]; // *Weird!!
            }
            NSLog(@"Now obj.weakProp = %@", [obj weakProp]);
        }
        NSLog(@"After autoreleased >> obj.weakProp = %@", [obj weakProp]);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-25
      • 1970-01-01
      • 2019-06-10
      • 2018-08-20
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      相关资源
      最近更新 更多