带有块和保留循环的 ARC
Posted
技术标签:
【中文标题】带有块和保留循环的 ARC【英文标题】:ARC with blocks and retain cycles 【发布时间】:2012-07-26 16:02:22 【问题描述】:我有一个将块作为对象属性的类:
@property (nonatomic, readwrite, copy) SFFailureBlock failureBlock;
SFFailureBlock:
typedef void (^SFFailureBlock)(NSError *error);
我有一个操作也声明为对象属性 (AFHTTPRequestOperation),我希望它在完成后调用失败块。
[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
__weak NSError *error = [NSError errorWithDomain:@"com.test" code:100 userInfo:@@"description": @"zero results"];
failureBlock(error);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"nothing");
];
我收到一个编译器警告“在此块中强烈捕获 'self' 可能会导致保留周期”。我已经搜索了互联网,但我找不到一个体面的解决方案来解释为什么这会导致保留周期。我不会在任何地方的块内调用“自我”。
另一个奇怪的事情是,如果我写了'self.failureBlock(error)',编译器不会给我任何警告!
谁能向我解释发生了什么事?我一定严重遗漏了 ARC 内存管理规则中的某些内容,但我无法弄清楚。
【问题讨论】:
【参考方案1】:当您在操作块中引用“failureBlock”时,您实际上是在执行“self-> failureBlock” - 所以它隐含地保留了 self。您可以做的是创建一个自动变量 SFFailureBlock xFailureBlock = failureBlock;上面的self操作,然后在block中使用它。 [再一次,你要避免任何 self-> INSIDE 的引用。]
【讨论】:
除非我弄错了,否则将示例中的 xFailureBlock 设置为 __weak 或 __unsafe_unretained 也是一个好主意。 我相信但不确定失败块的 xFailure auto var 是否会复制该块(然后被封闭块捕获)。 我明白了。但是,failureblock 不是控制器的实例属性吗?我认为一般来说,当我们执行“[self.myarray addObject:anObject];”之类的操作时在块内,则不保留“myArray”。我错了吗? 如果您建站,self 会被保留。就像您单独使用 myarray 一样。我在 Apple 的 ObjectiveC listserv 上发布了同样的问题,得到了这个答案:“当你在一个块中引用一个 Objective-C 实例变量时,self 被关闭,而不是变量本身。就好像你写了 self->foo = 是的; " 我忘了在上面提到的是苹果工程师提供了答案。以上是关于带有块和保留循环的 ARC的主要内容,如果未能解决你的问题,请参考以下文章