强制对象存活直到执行块的正确方法
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
我正在使用自动引用计数。 我希望对象在执行某些回调之前一直存在:
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