objective-c - 为什么将正在重新分配的对象设置为弱属性会导致崩溃

标签 objective-c clang automatic-ref-counting weak-references dealloc

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/

相关文章:

ios - 从属性中省略/删除 'strong' 属性时发出警告?

ios - Storyboard - 如何在没有动画和显示屏幕的情况下自动执行转场

iphone - 在应用程序购买/ View Controller 崩溃 : Message sent to deallocated instance

c++ - 检测对某些 C 函数的调用

c++ - 禁用编译

iphone - ARC 或不ARC iphone iOS5

xcode - 使用performSelector执行的方法中objc_retain崩溃

objective-c - 从 C# 背景学习 iPhone 编程

ios - CollectionView 中单元格之间的间距

c++ - 是否允许编译器优化堆内存分配?