[英]iOS - GCD weak and strong reference to self
I was always using __weak
references to self
when I was in a block in GCD
. 在GCD
,我一直在使用__weak
引用self
。 Everyone recommends that. 每个人都建议。 I know that strong reference to self
(tested) in GCD can't produce retain cycles. 我知道在GCD中对self
(经过测试)的强烈引用不会产生保留周期。 Apple recommends using a __weak
reference to self and then a __strong
reference to that _week
reference to guarantee that self
won't be nil
when the block is executed. Apple建议使用__weak
引用self,然后使用__strong
引用_week
引用,以确保执行该块时self
不会nil
。
I have the following piece of code: 我有以下代码:
- (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];
});
});
}
Test 1 I press the button and the Indicator is spinning. 测试1我按下按钮,指示器旋转。 I press the back button before the GCD finish and the GCDViewController is being released. 我在GCD完成并且GCDViewController被释放之前按下了返回按钮。
Test 2 Then I uncomment the strong reference to self and I execute the same procedure. 测试2然后,我取消对自我的强烈引用,并执行相同的过程。 The GCDViewController is not released until the block has finished it work. 在块完成工作之前,不会释放GCDViewController。 But then its released. 但随后被释放。
Test 3 Now if I refer directly to self (without __weak
or __strong
) I have the exact behaviour with Test 2. 测试3现在,如果我直接指代自我(没有__weak
或__strong
),我在测试2 __strong
具有确切的行为。
So if I want to make sure that the self won't be nil when the block is executed what's the point of using a __strong
reference to a __weak
reference to self
? 因此,如果我想确保在执行块时self不会为nil,那么对__weak
引用使用__strong
引用对self
何在? Do I miss something here? 我在这里想念什么吗? Is any example that would change the result of Test 2 & 3? 是否有任何示例会改变测试2和3的结果?
I was always using __weak references to self when I was in a block in GCD. 在GCD中的某个块中时,我一直在使用__weak引用self。 Everyone recommends that. 每个人都建议。
No. I don't know anyone that recommends that. 不,我不知道有人建议这样做。 Weak references make sense in some situations where there would be retain cycles. 在存在保留周期的某些情况下,弱引用是有意义的。 But whether a block should capture a weak or strong reference to any object (including the one self
points to) depends on the particular memory management design of the code in question and 但是,一个块应该捕获对任何对象的弱引用还是强引用(包括一个self
指向的对象),取决于所讨论代码的特定内存管理设计,并且
I know that strong reference to self (tested) in GCD can't produce retain cycles. 我知道在GCD中对自我(经过测试)的强烈引用不会产生保留周期。
Passing a block to dispatch_async
on a global or main queue will NEVER produce a retain cycle. 在全局或主队列上将一个块传递给dispatch_async
永远不会产生保留周期。
Now if I refer directly to self (without __weak or __strong) I have the exact behaviour with Test 2. 现在,如果我直接指代自我(没有__weak或__strong),我将具有测试2的确切行为。
Maybe you don't see any difference in this case. 在这种情况下,您可能看不到任何区别。 But they have different behavior in general. 但是它们通常具有不同的行为。 Basically, your question is what is the difference between the block capturing a strong or weak reference to the object pointed to by self
. 基本上,您的问题是,捕获对self
指向的对象的强引用或弱引用的块之间有什么区别?
The difference is in what happens, if the current object (object pointed to by self
) has been released by every other object that holds a strong reference to it, except potentially the block, and the block is executed afterwards asynchronously. 不同之处在于,如果当前对象(由self
指向的对象)已经被持有该对象强引用的所有其他对象(可能是该块)释放了,并且该块随后异步执行。
nil
at this point, and the block is not going to do anything with it (it is either going to check strongSelf
and return when it sees that it is nil
, or it will send messages to strongSelf
which is nil
which does nothing). 因此,该块的弱引用此时将为nil
,并且该块将不对其执行任何操作(它要么检查strongSelf
并在看到它为nil
时返回,否则将向其发送消息到strongSelf
nil
,什么都不做)。 So in one case stuff is done and in the other case nothing is done. 因此,一种情况下完成了工作,而另一种情况下则什么也没有做。
If the current object in your case is some UI element, like a view or view controller, then as long as it is in the view hierarchy, it is going to be retained by things in the view hierarchy, so you need to exit out of this view/view controller in order to have the situation where nothing else has a strong reference to it. 如果您当前的对象是某个UI元素(例如视图或视图控制器),则只要它在视图层次结构中,它就会被视图层次结构中的事物保留,因此您需要退出该视图/视图控制器,以便在没有其他东西对其有强烈引用的情况下。
In your case, all you do inside the block is [weakSelf.activityIndicator stopAnimating];
就您而言,您在块内要做的只是[weakSelf.activityIndicator stopAnimating];
, ie a change to the UI. ,即更改UI。 It doesn't matter whether this command is run or not, because, remember, the view containing this has already stopped displaying. 该命令是否运行无关紧要,因为请记住,包含该命令的视图已经停止显示。 Nobody can see this activity indicator. 没有人可以看到此活动指示器。 So what difference does it make if you stop it or not? 那么,如果不停止,有什么不同呢? But this is specific to this case. 但这是特定于此情况的。 In general, you can imagine that the command inside the block changes some global state, or sends something over the network or something, where there is a big difference between if you do it or not. 通常,您可以想象该块中的命令会更改某些全局状态,或者通过网络或某些内容发送某些内容,如果您不这样做,则两者之间会有很大差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.