在Clang的Objective-C自动引用计数中,我们看到以下内容:
对于__weak对象,lvalue将被更新为指向新的pointee,除非新的pointee是当前正在进行解分配的对象,在这种情况下,lvalue将被更新为null指针。这必须与对该对象的其他赋值、对该对象的读取以及新pointee的最终释放同时执行。
在objc-weak.mm中,我们在weak_register_no_lock()
中看到以下代码块:
if (deallocating) {
if (crashIfDeallocating) {
_objc_fatal("Cannot form weak reference to instance (%p) of "
"class %s. It is possible that this object was "
"over-released, or is in the process of deallocation.",
(void*)referent, object_getClassName((id)referent));
} else {
return nil;
}
}
我在我的UIViewController子类的dealloc方法中设置了一个断点,尝试在lldb中调用[self allowsWeakReference],结果为NO。
如果我们尝试将self设置为另一个对象的弱属性,则应用程序将按照objc-weak.mm代码崩溃。
问题是 - 为什么会发生这种情况?clang的规范是错误的吗?这是objc实现中的错误吗?
以下是一个简单的代码片段,可重现崩溃:
//cc -fmodules -fobjc-arc -g crash.m -o crash
@import Foundation;
@interface Foo : NSObject
@end
@implementation Foo
- (void)dealloc {
Foo * __weak weakSelf = self; // crashes on this line
}
@end
int main() {
(void)[[Foo alloc] init];
return 0;
}
weak_register_no_lock
源代码来看,当进行解除分配时它总是会崩溃。 - user102008