ios - 使用 block 和 ARC 导致 "message sent to deallocated instance"错误

标签 ios automatic-ref-counting objective-c-blocks

我遇到了 ARC 和 block 的问题,但已经解决了问题。不幸的是,我不知道到底发生了什么,想更多地了解我遇到的情况。

最初,我有执行此操作的代码

for(__block id<Foo> object in objects) {
    foo download:someParm
         success:^{
            object.state = StateNewState; 
         }
    ];
}

这导致了保留的不平衡。当一个对象被访问并且据说已经被释放时,就会发生崩溃。我编写了一个实现并使用“copy”属性创建 successBlock 属性的类,该属性保存了传递到下载函数的成功参数中的 block 。我用以下内容替换了代码

for(id<Foo> object in objects) {
    foo download:someParm
         success:^(id<Foo> successObject){
            successObject.state = StateNewState; 
         }
    ];
}

没有更多的释放对象错误,但我还没有运行工具来检查我是否没有泄漏。一些如何使用 __block 导致对象被释放太多次,我不明白为什么。我会继续研究这个问题的原因,但我认为这对你们其他人来说是一个值得思考的有趣问题。

我想可能值得注意的是,对象数组是一个自动释放的数组,它是在我在本文前面写下的代码的后续行中创建的。不要认为这很重要,但我认为我会在那里度过难关。我在这篇文章中放置的代码不是确切的代码,因为我正在使用它工作并且那里有一堆绒毛。但是在 for 循环中没有创建其他对象。

当应用程序崩溃时,它会运行下载,然后运行回调,顺便说一句,我正在使用 ASIHttp。当我尝试再次下载时,它会运行并且不会调用回调,因为对象已被释放并且委托(delegate)已被取消。在此之后,当对象被包含指向对象的指针的字典访问时,我们崩溃了。

最佳答案

Blocks Programming Topics说:

Use of instance variables within the block will cause the object itself to be retained. If you wish to override this behavior for a particular object variable, you can mark it with the __block storage type modifier.

If you are using ARC, object variables are retained and released automatically as the block is copied and later released.

因此,如果您不使用 __block,我想您会发现您的变量已为您保留。例如,这似乎对我有用:

NSMutableArray *array = [[NSMutableArray alloc] init];

// add two custom objects to that array

[array addObject:[[MyObject alloc] initWithText:@"One" number:1]];
[array addObject:[[MyObject alloc] initWithText:@"Two" number:2]];
[array addObject:[[MyObject alloc] initWithText:@"Three" number:3]];

// now replace the text field in each of the three objects with the word "Done"

for (MyObject *object in array)
{
    [self blockTestInvocation:^{
        NSLog(@"%s %@", __FUNCTION__, [NSDate date]);

        object.text = @"Done";
    }];
}

我发现当我的 blockTestInvocation 同步调用传递的 block 时,是否存在 __block 没有实质性影响,但是当我将它设置为调用时异步 block (在我的数组和对象本来会被释放之后),__block 的缺失确保了对象被保留,从而防止了可怕的“消息发送到释放实例”(并且有也没有泄漏)。但是对于 __block,对象不会被保留,因此可以在代码块尝试引用它时被释放。

关于ios - 使用 block 和 ARC 导致 "message sent to deallocated instance"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10804865/

相关文章:

ios - 如何在这个 block 中强烈修复 "Capturing ' block '很可能导致保留循环'

ios - 在 iOS 中播种 arc4random()

ios - 操作无法完成。 (com.facebook.sdk 错误 5.) FACEBOOK 视频上传

objective-c - 具有多个 View 时的“presentedViewController”

iphone - 由于僵尸对象,向下滚动会导致具有自定义 UITableViewCell 的 UITableView 上的应用程序崩溃

iphone - 检查互联网连接 iOS 5

ios - UiWebView 中的 Youtube

ios - SDWebImage 苹果 LLVM 6.0 错误

ios - 变量不在 block 外更新

ios - 在诸如fetchIfNeededInBackgroundWithBlock之类的 block 中使用PFObject的子类时出现问题