在Clang's Objective-C Automatic Reference Counting我们看到以下内容
For __weak objects, the lvalue is updated to point to the new pointee, unless the new pointee is an object currently undergoing deallocation, in which case the lvalue is updated to a null pointer. This must execute atomically with respect to other assignments to the object, to reads from the object, and to the final release of the new 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 设置为另一个对象的 weak 属性,应用程序将根据 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;
}
最佳答案
这不是错误:这显然是故意的。这是与规范的偏差,但它是有意的。
根据警告,听起来他们希望更容易诊断过度释放的情况,并且捕获当时正在释放的对象可能只是该主要目标的副作用。
他们可能还会考虑,如果你试图在被释放时弱化 self
,并且你没有检查 nil
weakref(很常见 -许多 block 代码通过弱引用重复调用,该引用随时可能变为 nil
!),您正在为难以调试的错误做好准备。
综上所述,我很想看到运行时更改背后的注释。
关于objective-c - 为什么将正在重新分配的对象设置为弱属性会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35991363/