Nil __block变量设置NSString

时间:2013-09-27 15:09:42

标签: ios objective-c warnings block

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

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中设置的变量的值,而不接收警告并且不从块中退出?

2 个答案:

答案 0 :(得分:2)

  

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

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

NSString *__weak weakString=AString;

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

Before

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

After

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

答案 1 :(得分:1)

假设aLabelanArray是视图控制器的ivars,您实际上只担心weakSelf,然后从那里引用任何ivars和属性。既然你有效地解除引用ivars,你就会在块中有一个强引用(因为你不能取消引用弱变量)。因此,假设aLabelanArrayaString为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中的“使用终身限定符以避免强引用周期”部分(稍后会谈到“非平凡周期”)。