2

为了避免保留周期和警告“在此块中强烈捕获自我可能会导致保留周期”,我为我的块中的每个对象添加了类似这样的内容

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

///the block code with some examples
 up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

       [weakSelf aMethodInTheController];
       [weakLabel setHidden:NO];
       [weakArray addObject:@"something"];

 };

使用弱引用,保留周期警告会消失,但是如果我在块内引入必须设置的 nnstring,则会出现问题

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

NSString *__weak weakString=AString;

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

   [weakSelf aMethodInTheController];
   [weakLabel setHidden:NO];
   [weakArray addObject:@"something"];
   weakString=@"atext";

 };

这样我收到错误“变量不可分配(缺少_块类型说明符)”,所以我添加了“ _block”

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

NSString *__weak weakString=AString;
__block NSString *BlockString =  weakString;    

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

[weakSelf aMethodInTheController];
[weakLabel setHidden:NO];
[weakArray addObject:@"something"];
 BlockString=@"atext";

 };

以这种方式,一切似乎都正常工作,至少在我进入块内之前......我原来的 Astring 变量是在我的 viewController 的 .h 中定义的,我必须稍后在块外访问它的值,但它是值始终为零。将 @"atext" 分配给 BlockString 不要为我的原始 Astring 变量设置值?我如何设置在我的 viewController 的 .h 中设置的变量的值而不收到警告并且不退出块?

4

2 回答 2

2

分配@"atext"不要BlockString为我的原始Astring变量设置值?

不,它没有设置Astring,也不应该设置它:当你这样做时

NSString *__weak weakString=AString;

您为变量__weak引用的对象创建第二个引用(恰好是)(例如,它是):AString@"some-text"

前

当您weakString在块内设置为 时@"atext",您将引用重新指向不同的对象,但该@"some-text"对象仍由AString变量引用:

后

如果要更改AString变量,请将其设置在块中。如果它是 ivar,请使用weakSelf->AString. 如果它是本地的,则添加__block到其声明中。

于 2013-09-27T15:17:57.997 回答
1

假设aLabelandanArray是视图控制器的 ivars,你真的只担心weakSelf,然后从那里引用任何 ivars 和属性。而且由于您正在有效地取消引用 ivars,因此您将在块内有一个强引用(因为您不能取消引用弱变量)。因此,假设aLabel, anArray, anaString是 ivars:

MyViewController *__weak weakSelf = self;

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

    MyViewController *strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf aMethodInTheController];
        [strongSelf->aLabel setHidden:NO];
        [strongSelf->anArray addObject:@"something"];
        strongSelf->aString = @"something else";
    }
};

坦率地说,我不喜欢取消引用 ivars,我宁愿使用属性(出于多种原因)。但两者都有效。

有关此模式的示例,请参阅Transitioning To ARC Release Notes的“使用生命周期限定符来避免强引用循环”部分(特别是稍后谈到“非平凡循环”)。

于 2013-09-27T15:54:02.593 回答