我遇到了 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)已被取消。在此之后,当对象被包含指向对象的指针的字典访问时,我们崩溃了。
最佳答案
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/