Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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
Objective c 强引用在块中,是否会保留?_Objective C_Objective C Blocks - Fatal编程技术网

Objective c 强引用在块中,是否会保留?

Objective c 强引用在块中,是否会保留?,objective-c,objective-c-blocks,Objective C,Objective C Blocks,我从公司的文档中发现了以下代码片段: __weak __typeof(self)weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ __strong __typeof(weakSelf)strongSelf = weakSelf; // Do stuff }); 它将被保留?块外的弱拷贝就足够了 __weak __typeof(self)weakSelf = self; dispatch_asyn

我从公司的文档中发现了以下代码片段:

__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
      __strong __typeof(weakSelf)strongSelf = weakSelf; 
      // Do stuff
});

它将被保留?

块外的弱拷贝就足够了

__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
      // silliness: __strong __typeof(weakSelf)strongSelf = weakSelf; 
      // Do stuff with weakSelf here
});
事实上,这也没关系:

dispatch_async(dispatch_get_main_queue(),
^{
    // self self self, go ahead and mention self here
});
一个人不能做的事情是把那个块复制到某个地方,然后在块中的某个地方提到那个地方

@property (nonatomic, strong) void (^myBlock)(void);

self.myBlock = ^void(void) {
    // don't mention self here!
};
这个想法是块保留他们提到的对象,我们试图避免循环,所以
object->block->another\u object
可以,但是
object->block->another\u object->任何数量的间接操作->object
都是循环,这很糟糕

循环是不好的,因为如果对象被保留在其他地方,它就不能被释放,因此它保留的东西也不能被释放。如果两个东西互相保留,那么它们都被卡住了,无法释放,因为它们都被某个东西保留了

编辑直到今天我一直误解的是,弱var的强拷贝并不总是愚蠢的。它可能是相关的,但有意义的案例是高度合格的)。

如果您使用此选项:

__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{ 
    // Do stuff
});
在执行块时,Self可能会被解除分配。因此,我们最好将weakSelf转换为strongSelf,以确保self在块完成执行之前一直保留在内存中


使用
\uuuu strong\uuuu typeof(weakSelf)strongSelf=weakSelf
后,self将引用本地堆栈变量。因此它不会被保留。

在块中捕获
引用有两个原因

  • 避免保留循环

  • 创建无操作情况

  • 前者已被讨论得异常激烈。第二个更有趣

    示例

    所讨论的块是图像下载的完成处理程序。下载完成后,将在图像视图中显示

    如果图像视图已经被解除分配(比如用户已经切换到新视图),则无需执行任何操作。不存在保留循环的危险,因为图像视图没有对块的引用。但是,捕获
    引用允许在执行块之前取消分配图像视图。因此,如果用户在下载图像之前切换视图,则块将停止任何操作,因为其
    引用已被
    nil
    删除。如果图像视图在块的执行过程中被取消分配,也无所谓,因为它只是将图像视图上的操作变为无操作,而不是把整个街区变成禁区

    但是,有时,块需要无操作行为,但仅当引用开始时(或到达代码路径中的某个点时)已经是
    nil
    。如果在执行块时,对象处于活动状态,则块必须全部执行。它不能中途停止,因为对象已在其他线程上解除分配

    示例

    完成块的目的是向图像中添加由字符串定义的标题。如果字符串已被释放,则不添加标题。但是,如果在后处理开始时字符串仍然处于活动状态,则它必须保持活动状态,以避免尝试创建带有
    nil
    引用的属性化字符串,因为这会导致崩溃


    在这种情况下,最好使用
    引用捕获字符串,这样它就可以被其他线程释放(导致没有标题)。但是,在块中使用字符串之前,必须将其捕获
    strong
    ly,以避免在创建属性字符串时崩溃。

    这是使用块避免保留循环的正确方法。强引用是指弱引用,因此可以避免保留循环。我通常使用
    \u strong typeof(self)strongSelf=weakSelf因为
    self
    在这两种情况下是相同的。但是,我认为块外的弱引用就足够了。是吗?是的,您是对的,或者只是在块外引用为
    \uu弱类名*weakSelf=self并在块内使用weakSelf变量。苹果的块编程指南仅显示使用weakSelf,然而,在2012年WWDC视频异步设计模式中,块、GCD和XPC使用strongself作为一种手段,在块中执行代码之前检查self是否为零。这是我一直使用的方法。但是为什么他们要使用强自我呢?我也见过几次,这是因为有人不理解复制其他人不理解的代码。在块中使用弱引用的强版本是有原因的。这不是误会的结果,尽管它可能被那些不理解的人过度使用。在块内创建强引用可确保如此引用的对象在块执行期间保持活动状态。如果没有这一保证,对象可能会被部分释放。有时这是可以的,有时不是。@danh
    weakSelf
    的全部要点是阻止,不要保留它。因此,需要
    strongSelf
    将弱引用转换为强引用reference@BryanChen-是的,这是需要的,当弱者自己或它保留的东西保留块。如果这个循环不存在,那么懦夫就没有必要。而区块内的“强”声明是多余的。谢谢你的好文章,但是我不能仅仅从英语就知道你在说什么。你能添加与叙述相匹配的代码吗?此外,在我看来,这两个示例都可以直接编写代码,而无需向未恢复的堆栈变量添加任何有趣的强限定引用。嘿,这让我很头疼,所以我问了一位在苹果iOS上工作的朋友。简而言之,你是对的。我们使用weakSelf来避免循环,使用强拷贝来防止在执行块期间释放。支票