使用块和ARC正在引起“发送到已释放实例的消息".错误 [英] Using blocks and ARC is causing a "message sent to deallocated instance" error

查看:80
本文介绍了使用块和ARC正在引起“发送到已释放实例的消息".错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用ARC和块时遇到了问题,但是已经解决了该问题.不幸的是,我没有真正发生的事情,而是想了解更多有关我所处情况的信息.

I had a problem with ARC and blocks but have solved the problem. Unfortunately I don't what exactly is going on and would like to learn more about the situation I had.

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

Originally, I had code that did this

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

这导致保留不平衡.当访问一个对象并且据说该对象已经被释放时,发生崩溃.我编写了一个类,该类实现并使用"copy"属性创建了successBlock属性,该属性将传递的块保存到了download函数的success参数中.我用以下

This caused an imbalance in retains. A crash occurs when an object is accessed and is said to be already deallocated. I wrote a class that implemented and used the "copy" attribute to create a successBlock property which saved the block passed into the success parameter of the download function. I replaced the code with this with the following

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

不再释放对象错误,但是我还没有运行仪器来检查是否没有泄漏.一些使用__block的方式导致对象被释放太多次,我不知道为什么.对于该问题的起因,我将继续进行研究,但我认为,对于其他所有人来说,这将是一个有趣的问题.

No more deallocated object errors but I have yet to run instruments to check if I'm not leaking. Some how using __block is causing the object to be released too many times, and I can't figure out why. I'll continue my research as to the cause of this issue but I thought it'd be an interesting problem for the rest of you guys to think about.

我想可能值得注意的是,对象数组是自动释放的数组,它是在我在本文前面写下的代码的前几行中创建的.没关系,但我认为我只是要解决那个问题.我在这篇文章中输入的代码不是确切的代码,因为我正在使用它进行工作,并且那里有一堆绒毛.但是在for循环中没有其他对象正在创建.

I suppose it may be worth noting that the objects array was an autoreleased array that was created in the lines proceeding the code I wrote down earlier in this post. Don't think it'd matter but I thought I'd just through that out there. The code I put in this post isn't the exact code, because I'm using this for work and there's a bunch of fluff in there. But there's no other objects being created in the for loop.

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

When the app crashes, it runs download and then later runs the callback, I'm using ASIHttp by the way. When I attempt to download again it runs and the callback is not called, since object has been deallocated and the delegate is nil'ed. After this when object is accessed by a dictionary that contains a pointer to object we crash.

推荐答案

在块中使用实例变量将导致对象 本身要保留.如果您想覆盖此行为,请执行以下操作: 特定的对象变量,可以用__block存储标记它 类型修饰符.

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.

如果使用的是ARC,则对象变量将在复制并随后释放时自动保留并释放.

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

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

Thus, if you don't use __block, I think you'll find your variables are being retained for you. E.g., this seems to work for me:

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时,不会保留该对象,因此可以在代码块尝试引用该对象时将其释放.

I found that the presence or absence of __block didn't have a material impact when my blockTestInvocation invoked the passed block synchronously, but when I set it up to invoke the block asynchronously (after my array and objects would have otherwise been released), the absence of the __block ensured that the object was retained, thereby preventing the dreaded "message sent to deallocated instance" (and there were no leaks, either). But with __block, the object is not retained, and thus could be deallocated by the time the block of code tries to reference it.

这篇关于使用块和ARC正在引起“发送到已释放实例的消息".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆