我有一组看起来像这样的代码:
if(self.property == A) {
[self.infoManager getThingA:^(NSString *thing, NSError *error) {
self.textView.text = thing;
}];
} else if(self.property == B) {
[self.infoManager getThingB:^(NSString *thing, NSError *error) {
self.textView.text = thing;
}];
}
基本上,在这两种情况下,他们只是获取一个字符串来发布到TextView。字符串根据调用的方法而不同。
作为一般反对代码重复的人,我将其抽象为块变量:
void (^stringBlock)(NSString *thing, NSError *error) = ^void(NSString *thing, NSError *error) {
self.textView.text = thing;
}
if(self.property == A) {
[self.infoManager getThingA:stringBlock];
} else if(self.property == B) {
[self.infoManager getThingB:stringBlock];
}
一切都很好。但是现在我的单元测试中出现了错误,因为看起来stringBlock过早被释放了。我想这是因为我在块运行后得到了EXC_BAD_ACCESS,调试器说stringBlock为NULL。
我没有在我的方法或单元测试中明确复制块。
答案 0 :(得分:1)
上面声明的块称为独立块(其他类型称为内联块,类似于java中的内联匿名类)。当使用独立块时,我们需要遵守一些规则。
1.您不能在独立块对象中引用self。如果需要,必须将self对象作为参数传递给块。
2.您无法使用点表示法访问独立块内对象的属性。如果需要,请使用setter和getter方法。
...
所以在你的情况下,我们需要将self对象传递给块,如下所示。
void (^stringBlock)(NSString *thing, NSError *error, id self) =
^void(NSString *thing, NSError *error, id self) {
self.textView.text = thing;
}