【问题标题】:ARC with blocks and retain cycles带有块和保留循环的 ARC
【发布时间】: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 内存管理规则中的某些内容,但我无法弄清楚。

【问题讨论】:

    标签: ios memory-management automatic-ref-counting afnetworking


    【解决方案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 = 是的; "
    • 我忘了在上面提到的是苹果工程师提供了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多