iOS 4阻止并保留计数 [英] iOS 4 blocks and retain counts

查看:85
本文介绍了iOS 4阻止并保留计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用积木和Grand Central Dispatch。我被告知(并阅读 Apple文档)从块中引用的任何对象都被保留。

I'm just getting started with blocks and Grand Central Dispatch. I've been told (and read in the Apple Documentation) that any object referenced from within a block gets retained.

例如:

^{  
    self.layer.transform = CATransform3DScale(CATransform3DMakeTranslation(0, 0, 0), 1, 1, 1);
    self.layer.opacity = 1;
}

self被保留以便泄漏。为了避免这种情况,我需要将self分配给:

"self" gets retained so it leaks. To avoid that, I need to assign self to:

__block Object *blockSelf = self;

然后使用 blockSelf 而不是 self 在我的区块内。

and then use blockSelf instead of self inside my block.

我的问题是:当您的块有更多代码并引用多个对象时会发生什么?我是否需要将它们全部分配给 __ block 对象?例如:

My question is: what happens when your block has a lot more code and references several objects? Do I need to assign them all to __block objects? For instance:

^{  
    [self doSomething];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"prevName == %@", artistName];
    [request setEntity:entity];
    [request setPredicate:predicate];

    Object *newObject = [[Object alloc] init];
    [someArray addObject];
    [newObject release];
}


推荐答案

不。当您的块保留一个保留它的对象时,会发生此问题。您的块将保留它引用的任何对象,但使用 __ block 注释的对象除外。因此:

No. The problem occurs when your block retains an object which retains it. Your block will retain any object that it references, except for those annotated with __block. Hence:

// The following creates a retain cycle which will leak `self`:
self.block = ^{
  [self something];
};

self 保留阻止阻止隐式保留 self 。如果您引用 self 的实例变量,也会发生

self retains block, and block implicitly retains self. This will also happen if you reference instance variables of self.

// The following avoids this retain cycle:
__block typeof(self) bself = self;
self.block = ^{
  [bself something];
};

__ block 注释的变量是可变的(对于指针,即它们指向的
地址可以改变);因此,
保留该对象是没有意义的,因为您需要将该对象视为局部变量
(因为,它可以被重新分配,影响块范围之外的对象) )。因此, __ block 不会被块保留。

Variables annotated with __block are mutable (for pointers, that is, the address they point to can be changed); as a result, it makes no sense to retain that object, since you need to treat that object as a local variable (as in, it can be reassigned, affecting an object outside the scope of the block). Thus, __block don't get retained by blocks.

但是,现在如果你遇到无法预料的问题尝试以某种方式使用此块。例如,如果您决定以某种方式延迟调用此块,并且 self 在执行该块时已被释放,则程序将崩溃,因为您是向已释放的对象发送消息。那么你需要的是一个弱引用,它不是在非垃圾收集环境中开箱即用的!

But, now you can run into unforeseen problems if you try to use this block in certain ways. For instance, if you decide to delay the invocation of this block somehow, and self has been deallocated by the time you execute that block, your program will crash, since you're sending a message to a deallocated object. What you need then is a weak reference, which is not provided out-of-the-box in the non-garbage-collected environment!

一种解决方案是使用< a href =http://www.mikeash.com/pyblog/introducing-mazeroingweakref.html\"rel =noreferrer> MAZeroingWeakRef 来包裹你的块;如果您尝试发送消息 self ,这将使指针归零以便您最终发送消息到 nil self 已被解除分配后:

One solution is to use MAZeroingWeakRef to wrap your block; this will zero out the pointer so that you'll just end up sending messages to nil should you attempt to message self after self has been deallocated:

MAZeroingWeakRef *ref = [MAZeroingWeakRef refWithTarget:self];
self.block = ^{
  [ref.target something];
};

我还实现了 Objective-C ++中的弱引用包装器,它提供了更轻量级语法的好处:

I've also implemented a weak reference wrapper in Objective-C++, which provides the benefit of a more lightweight syntax:

js::weak_ref<SomeClass> ref = self;
self.block = ^{
  [ref something];
};

因为 js :: weak_ref 是一个类模板,你会得到方便的强类型(也就是说,如果你试图发送一个它似乎没有响应的消息,你会在编译时收到警告)。但迈克的 MAZeroingWeakReference 比我的成熟得多,所以我建议使用他,除非你想弄脏你的手。

Because js::weak_ref is a class template, you'll get handy strong-typing (that is, you'll get warnings at compile-time if you try to send the reference a message which it doesn't appear to respond to). But Mike's MAZeroingWeakReference is a lot more mature than mine, so I'd suggest using his unless you want to get your hands dirty.

要阅读有关 __ block 问题的更多信息以及弱引用的用例,请阅读使用块,正确的方式避免保留周期 Jonathan Rentzsch的回复

To read more about issues with __block and the use-case for weak references, read Avoiding retain cycles with blocks, a right way and Jonathan Rentzsch's response.

这篇关于iOS 4阻止并保留计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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