Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.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
iOS-GCD对自我的弱引用和强引用_Ios_Objective C_Objective C Blocks - Fatal编程技术网

iOS-GCD对自我的弱引用和强引用

iOS-GCD对自我的弱引用和强引用,ios,objective-c,objective-c-blocks,Ios,Objective C,Objective C Blocks,当我在GCD的一个块中时,我总是使用\uu弱引用self。每个人都建议这样做。我知道在GCD中强烈引用self(tested)不能产生保留周期。 Apple建议对self使用\uuu-weak引用,然后对该\uu-week引用使用\uu-week引用,以确保执行块时self不会为零 我有以下代码: - (IBAction)startGCD:(id)sender { GCDVC* __weak weakSelf = self; [self.activityIndicator s

当我在
GCD
的一个块中时,我总是使用
\uu弱
引用
self
。每个人都建议这样做。我知道在GCD中强烈引用
self
(tested)不能产生保留周期。 Apple建议对self使用
\uuu-weak
引用,然后对该
\uu-week
引用使用
\uu-week
引用,以确保执行块时
self
不会为

我有以下代码:

- (IBAction)startGCD:(id)sender {

    GCDVC* __weak weakSelf = self;

    [self.activityIndicator startAnimating];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1

        // VC2* __strong strongSelf = weakSelf;

        [weakSelf.proArray addObject:@"2"];

        [NSThread sleepForTimeInterval:10];

        NSLog(@"%@",weakSelf.proArray);

        dispatch_async(dispatch_get_main_queue(), ^{ // 2
            [weakSelf.activityIndicator stopAnimating];
        });
    });

}
测试1 我按下按钮,指示灯开始旋转。在GCD完成之前,我按下后退按钮,GCDViewController将被释放

测试2 然后我取消对self的强引用的注释,并执行相同的过程。GCDViewController在块完成其工作之前不会释放。但后来它被释放了

测试3 现在,如果我直接引用self(没有
\uuuuu-weak
\uuuu-strong
),我就有了测试2的确切行为

因此,如果我想确保在执行块时self不会为零,那么使用
\uuu strong
引用
\uu弱
引用
self
有什么意义?我错过什么了吗?是否有任何示例会改变测试2和3的结果

当我在一个街区的时候,我总是对self使用弱引用 GCD。每个人都建议这样做

不,我不知道有谁推荐这个。弱引用在某些可能存在保留循环的情况下是有意义的。但是,一个块是否应该捕获对任何对象(包括
self
指向的对象)的弱引用或强引用,取决于所讨论代码的特定内存管理设计,以及

我知道GCD中对自我测试的强烈引用不能产生 保持循环

将块传递给全局或主队列上的
dispatch\u async
,将永远不会产生保留循环

现在如果我直接指自我(没有弱或强),我有 测试2的准确行为

也许你看不出这件事有什么不同。但他们一般有不同的行为。基本上,您的问题是捕获对
self
指向的对象的强引用或弱引用的块之间有什么区别

不同之处在于,如果当前对象(self所指向的对象)已被所有其他具有强引用的对象(可能是块除外)释放,并且该块随后异步执行,则会发生什么

  • 如果块捕获了对当前对象的强引用,那么该引用将在整个时间内保持对象的活动状态。所以这个对象仍然是活动的,我们可以使用它并向它发送消息,等等
  • 如果块捕获了对当前对象的弱引用,则当前对象在释放对它的最后一个强引用时已被解除分配。因此,此时块的弱引用将是
    nil
    ,而块不会对它做任何事情(它将检查
    strongSelf
    ,并在看到它是
    nil
    时返回,或者它将向
    strongSelf
    发送消息,后者是
    nil
    ,而后者什么也不做)
因此,在一种情况下,事情已经完成,而在另一种情况下,什么也没做

如果您案例中的当前对象是某个UI元素,如视图或视图控制器,那么只要它在视图层次结构中,它就会被视图层次结构中的事物保留,因此您需要退出此视图/视图控制器,以便在没有其他对象对它有强引用的情况下


在您的情况下,您在块内所做的只是
[weakSelf.activityIndicator stop animating],即对UI的更改。是否运行此命令无关紧要,因为,请记住,包含此命令的视图已经停止显示。没有人能看到这个活动指示器。那么,如果你停止或不停止,又有什么区别呢?但这是本案所特有的。一般来说,您可以想象块内的命令会更改某些全局状态,或通过网络或其他方式发送某些内容,如果您这样做或不这样做,两者之间会有很大区别。

您在块内创建了一个强引用,以防止在块运行时释放self。是的,我知道这一点。但是,自强与直接呼唤自我有什么区别呢?如果我直接给self打电话,我会像给strong打电话一样增加保留次数。两种情况下的输出都是相同的,如果您在块中直接引用self,那么只要块存在,它就会阻止self被释放。创建块外的弱自我,然后创建块内的强自我,允许在块存在时释放自我,并且只在块运行时阻止它。在您的示例中,差异是无关的,因为块立即执行。如果对块的引用被某个东西保留,然后再执行,那么这很重要。你是说一个简单的块,但不在GCD中?例如,在强特性中指定块时?