Хотя в 2020 году довольно глупо, что я все еще задаю вопрос об Obj C, пожалуйста, будьте терпеливы и внимательны ...
Я читаю исходный код 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
освобождается за пределами области действия {}
. С другой стороны, если он не закомментирован, он печатает <NSObject: 0xxxxx>
, что указывает на то, что prop
каким-то образом удерживается кем-то (или по любой другой причине?). Что здесь происходит??! (BlocksKit ведет себя так же!)
Среда: XCode 10.3