Sno*_*man 5 iphone objective-c ios
在这个问题中,我询问了以下代码并保留了周期:
__weak Cell *weakSelf = self;
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
UIImage *image = /* render some image */
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf setImageViewImage:image];
}];
}];
[self.renderQueue addOperation:op];
Run Code Online (Sandbox Code Playgroud)
所有答案都指出在这里使用弱引用不是必需的,因为此代码不会导致保留周期.但是,在尝试更多代码时,以下操作会导致保留周期(如果我不使用弱引用,则不会释放当前视图控制器)
//__weak ViewController *weakSelf = self;
MBItem *close = [[MBItem alloc] initWithBlock:^{
[self dismissModalWithDefaultAnimation:NO];
}];
NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:close, nil];
[self.childObject setItems:items];
Run Code Online (Sandbox Code Playgroud)
为什么第二个会导致保留周期而不是第一个?
rob*_*off 12
如果您不使用__weak以下内容,则旧代码会创建此保留周期:
(NSBlockOperation *)op 保留外部区块self(如果您不使用__weak)self 保留 (NSOperationQueue *)renderQueue(NSOperationQueue *)renderQueue 保留 (NSBlockOperation *)op除非其中一个链接被破坏,否则该循环中的所有对象都不能被释放.但是你向我们展示的代码确实打破了保留周期.当op执行完毕后,renderQueue将其释放,打破了保留周期.
我怀疑你的新代码创建了这个保留周期:
(MBItem *)close 保留块selfself 保留 childObjectchildObject 保留 (NSMutableArray *)items(NSMutableArray *)items 保留 (MBItem *)close如果没有任何事情可以破坏其中一个链接,则循环中的所有对象都不能被释放.您没有向我们展示任何打破保留周期的代码.如果没有明确破坏它的事件(例如通过清除childObject.items),那么您需要__weak用来打破保留周期.
我不能告诉你第二个例子中保留周期的原因,因为我不知道MBItem,但是有两种不同的使用模式.
如果您希望在任何情况下执行块,那么您可以self在块中使用:
[startSomeOperationWithCompletionBlock:^{
[self doSomeThing];
}];
Run Code Online (Sandbox Code Playgroud)
该块保留对该引用的引用self,因此self在执行该块之前不会释放该引用.但是块执行后,此引用(以及保留周期)消失了.
如果您可能希望在执行块之前self取消分配,或者可能根本不调用该块,则必须使用弱引用并检查块内的值:
__weak MyClass *weakSelf = self;
[startSomeOperationWithCompletionBlock:^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomeThing];
}
}];
Run Code Online (Sandbox Code Playgroud)
self在这种情况下,块不会保留,因此self可以取消分配.在这种情况下,weakSelf设置为nil自动.因此,如果最后执行该块,则必须首先检查是否weakSelf仍然有效.(或者您可以使用它,因为发送消息nil是无操作.)
strongSelf在块内部分配强引用可防止self在块执行时被释放.
| 归档时间: |
|
| 查看次数: |
4063 次 |
| 最近记录: |