为了避免保留周期和警告“在此块中强烈捕获自身可能会导致保留周期”我已经为我的块中的每个对象添加了类似这样的内容
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中设置的变量的值,而不接收警告并且不从块中退出?
答案 0 :(得分:2)
将
@"atext"
分配给BlockString
不要将值设置为我原来的Astring
变量?
不,它没有设置Astring
,也不应该设置它:当你这样做时
NSString *__weak weakString=AString;
您为__weak
变量引用的对象创建了第二个引用(恰好是AString
)(例如,它是@"some-text"
):
当您将块中的weakString
设置为@"atext"
时,您将引用重新指向其他对象,但@"some-text"
对象仍由AString
变量引用:
如果要更改AString
变量,请将其设置在块内。如果是ivar,请使用weakSelf->AString
。如果是本地的,请在其声明中添加__block
。
答案 1 :(得分:1)
假设aLabel
和anArray
是视图控制器的ivars,您实际上只担心weakSelf
,然后从那里引用任何ivars和属性。既然你有效地解除引用ivars,你就会在块中有一个强引用(因为你不能取消引用弱变量)。因此,假设aLabel
,anArray
,aString
为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中的“使用终身限定符以避免强引用周期”部分(稍后会谈到“非平凡周期”)。