对象可以在方法执行期间被释放吗?

Can an object be deallocated during method execution?

假设我们在主线程上创建了一个 class var foo: Foo? = Foo() 的实例,我们在另一个线程上调用了 Foo 的一些耗时的实例方法 bar,不久之后,我们在主线程上将 foo 设置为 nilbar 的执行会发生什么,在我的理解中 bar 仍然应该继续执行,因为调用实例方法隐式地将 self 作为第一个参数传递,所以即使那些最后显式引用 foo 被破坏了,我们在一个方法中仍然有一个引用,它应该是好的。但是后来我发现这个 Whosebug post 完全打破了我的理解。那么,有人可以 confirm/deny 对象在其方法执行期间不能被释放的事实

简短的回答是你的信念是正确的,你正在看一个与 Swift 无关的问题。

您的 link 是非 ARC Objective-C。 Swift一直用ARC,ARC对retains很保守。考虑以下 Objective-C 调用:

[target runMethod: parameter];

在 ARC 下,这(概念上)转换为:

[target retain];
[parameter retain];
[target runMethod: parameter];
[parameter release];
[target release];

retainrelease 是原子的、线程安全的调用。

Swift 中存在类似的行为。正因为如此,作为一般规则(在没有 Unsafe 的情况下),当你持有一个变量时,它不能“消失”。

这是实现细节。更好的思考方式是,默认情况下变量和参数都是强引用,并且在存在强引用时无法销毁对象。这符合你的理解。

但是,在 ARC 之前,您需要自己插入额外的保留和释放以防止出现这种情况,而通常不这样做是很常见的。 (在 10.6 之前,大多数 ObjC 都是单线程的。)

即使没有线程,如果没有 ARC,也有一些方法会误入歧途。由于调用者通常不会立即保留返回值,如果他们只是临时需要的话,即使没有多线程也有可能得到悬空指针。例如,使用没有内存管理的普通访问器,这可能会崩溃:

NSString *name = [person name];
[person release];
[self doSomethingWithName: name];

这就是为什么您经常看到旧的 ObjC getter 以以下形式编写:

- (NSString*) title {
    return [[title retain] autorelease];
}

即使 self 释放它或 self 被释放,这也确保了返回的值会一直存在到事件循环结束。

Swift 通过 ARC 做类似的事情,但顾名思义,它是自动的。