Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 强制对象生存直到执行块的正确方法_Ios_Objective C_Objective C Blocks - Fatal编程技术网

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

Ios 强制对象生存直到执行块的正确方法,ios,objective-c,objective-c-blocks,Ios,Objective C,Objective C Blocks,我正在使用自动参考计数。 我希望对象一直存在,直到执行某个回调: Foo *obj = [[Foo alloc] init]; [obj someMethod: @"AAA", ^(NSError * _Nullable error) { //callback }); 我需要obj在调用“callback”之前一直处于活动状态, 但我实际上并没有在回调中使用它。 现在,我用以下方法“解决”它: 但这看起来很奇怪。这种情况可能有一些语言结构, 或者除了打印到日

我正在使用自动参考计数。 我希望对象一直存在,直到执行某个回调:

 Foo *obj = [[Foo alloc] init];
 [obj someMethod: @"AAA", ^(NSError * _Nullable error) {
    //callback
  });
我需要
obj
在调用“callback”之前一直处于活动状态, 但我实际上并没有在回调中使用它。 现在,我用以下方法“解决”它:

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

如果在块内使用外部变量
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

@马特没有帮助,调用
someMethod
和调用callback
obj
之间有足够长的延迟,无论我如何定义它
\uuuu block Foo*obj=
或者仅仅
Foo*obj=
为什么需要它?@user1244932:声明
\uu block Foo*objobj
实际上未在块内引用,则code>不会更改行为。如果它被引用,则不需要使用
\u block
来使
obj
保持活动状态。我认为它只取决于
Foo
类及其方法实现
Foo
应在回调前保留selfcall@RomanPodymov因为程序不能正常工作,若
Foo
对象会在调用回调之前被销毁,但这将是“未使用的变量”。因此,处于释放模式的编译器可以将其删除?在这种情况下,编译器无法优化该变量,因为它会产生副作用——特别是保留和释放对象引用。我测试了它:它保持不变。除此之外,警告“unused variable”告诉您,这种保持对象活动的方式不是很有表现力;你至少应该评论一下意图。@kish-我正在思考,你可以做
obj内部块。你也能测试一下吗?我肯定编译器会抱怨,但我想它会的。这整件事都是关于变量进出范围的。在Obj-C中,你可以用它做各种各样的好事,就像这个家伙所做的那样@skaak:是的,你的建议很有效。我喜欢它,因为它没有引入额外的局部变量名。你甚至可以做
(void)obj
,这几乎写下了意图。@kisch-谢谢你测试它并给出反馈。。。我不会做
void
的事情,那是为了那些不知道如何关闭编译器警告的人。。。谢谢,我看到你也更新了你的答案。
__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