强制对象存活直到执行块的正确方法

Proper way to force object to live until block will be executed

我正在使用自动引用计数。 我希望对象在执行某些回调之前一直存在:

 Foo *obj = [[Foo alloc] init];
 [obj someMethod: @"AAA", ^(NSError * _Nullable error) {
    //callback
  });

我需要 obj 活着,直到调用“回调”, 但我实际上并没有在回调中使用它。 现在我“解决”它:

[obj someMethod: @"AAA", ^(NSError * _Nullable error) {
    //callback
    NSLog(@"To make sure that obj alive print it: %@", obj);
  });

但这看起来很奇怪。对于这种情况可能有一些语言结构, 或者有一些典型的解决方法,除了打印到日志?

如果在块内使用外部变量obj,那么它的值会被捕获到块中。这将创建对该对象的附加引用,以便自动引用计数使其保持活动状态,直到该块已执行。

要保留该引用,您不需要将其传递给另一个函数,例如 NSLog()。将其存储在局部变量中就足够了。

Foo *obj = [[Foo alloc] init];
[obj someMethod: @"AAA", ^(NSError * _Nullable error) {
    Foo* keepObj = obj; // keeps obj alive
    //callback
});

编辑:根据 skaak 的反馈改进解决方案: 不需要未使用的局部变量名称,您可以通过转换为 void.

来表示意图
Foo *obj = [[Foo alloc] init];
[obj someMethod: @"AAA", ^(NSError * _Nullable error) {
    //callback
    (void) obj; // release reference that kept obj alive
});

要手动管理对象的生命周期,您可以通过在块内设置 nil 来捕获它,例如:

__block Foo *obj = [Foo new];
[obj someMethod:@"AAA" block:^(NSError * _Nullable error) {
    NSLog(@"start block");
    
    ...
    
    obj = nil;
    NSLog(@"end block");
}];

NSLog(@"finish");


Prints:

start block
Foo dealloc
end block
finish