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中?例如,在强特性中指定块时?