【问题标题】:Will self retain within block?将自我保留在块内吗?
【发布时间】:2023-12-15 06:28:01
【问题描述】:

在调用块之前/之后,retaincount 始终为 1。 从apple block doc 我们知道self 应该保留。谁能知道为什么?

NSLog(@"Before block retain count: %d", [self retainCount]);    
void (^block)(void) = ^(void){
    UIImage* img = [UIImage imageNamed:@"hometown.png"];
    [self setImage:img];
    NSLog(@"After block retain count: %d", [self retainCount]);
};
block();

【问题讨论】:

    标签: objective-c ios block retain self


    【解决方案1】:

    首先,retainCount 没用。不要叫它。

    块仅在复制块时保留捕获的对象。因此,self 不会被该示例中的块保留。

    【讨论】:

    • 在文档中它刚刚说:在引用计数环境中,默认情况下,当您在块中引用 Objective-C 对象时,它会被保留。即使您只是引用对象的实例变量也是如此。但是,使用 __block 存储类型修饰符标记的对象变量不会被保留。苹果文档真的让我很困惑。谢谢bbum。
    • 请在文档上提交一个错误,然后。我同意——这并不完全清楚。应该更明确的是,保留 可能 仅在复制块并且围绕实例变量的语言也有点偏离时发生。
    【解决方案2】:

    好的,我做了一些研究,现在事情变得更清楚了。首先,我没有在block1上使用@property,也就是说我设置它的时候,没有复制任何东西,所以它们不会被保留,其次,如果我们进行[块复制],变量将被保留,如果我们不复制, 块指向一个栈地址,复制到堆中保证安全。

    变量'array'是一个Member变量,所以不保留,同时self也会保留,不管你放不放块,如果变量是局部变量,都会保留。 (这是我仍然困惑的事情,为什么不保留成员变量,而是在保留计数上再添加一个自我???请回答我?)

    使用块后,我们可以将其设置为 nil self.block = nil;使变量释放,并避免保留循环。

    PS。打破保留循环的方法是使用 __block id weakSelf = self;在块中,所以这意味着__block变量也没有保留。

    【讨论】: