ARC 和块语法 EXC_BAD_ACCESS
ARC and Block syntax EXC_BAD_ACCESS
如果这个属性是'strong',就没有问题。但是,如果这个 属性 是 'weak',那么我会收到错误 EXC_BAD_ACCESS。
@property (weak, nonatomic) void(^pickerCompletion)(NSDate *date);
-(void)textFieldDidEndEditing:(UITextField *)textField {
if (self.pickerCompletion) self.pickerCompletion(self.date);
}
我正在使用 if 语句来检查 属性 是否为 nil,那么这里的问题是什么?
如果 ARC 清除了这个指针,那么我希望 if 语句求值为 false 并且不执行该块。
@property (strong, nonatomic) void(^pickerCompletion)(NSDate *date);
如果属性是strong
,编译器会自动复制块。 pickerCompletion
拥有复制块(堆块)的所有权。
@property (weak, nonatomic) void(^pickerCompletion)(NSDate *date);
但是如果属性是weak
,编译器什么都不做,只是把指针值赋给变量。如果指针是 Stack Block(只是普通的块文字),指针值永远不会被 ARC 填零。难道你没有从编译器那里得到警告信息吗?
warning: assigning block literal to a weak property; object will be
released after assignment
此外还有竞争条件。
if (self.pickerCompletion) self.pickerCompletion(self.date);
在多线程环境中,self.pickerCompletion
可以在 if (self.pickerCompletion)
之后的 self.pickerCompletion(self.date)
之前补零。使用临时 __strong
变量来安全访问弱对象。
void(^pickerCompletion)(NSDate *date) = self.pickerCompletion;
if (pickerCompletion) pickerCompletion(self.date);
如果这个属性是'strong',就没有问题。但是,如果这个 属性 是 'weak',那么我会收到错误 EXC_BAD_ACCESS。
@property (weak, nonatomic) void(^pickerCompletion)(NSDate *date);
-(void)textFieldDidEndEditing:(UITextField *)textField {
if (self.pickerCompletion) self.pickerCompletion(self.date);
}
我正在使用 if 语句来检查 属性 是否为 nil,那么这里的问题是什么?
如果 ARC 清除了这个指针,那么我希望 if 语句求值为 false 并且不执行该块。
@property (strong, nonatomic) void(^pickerCompletion)(NSDate *date);
如果属性是strong
,编译器会自动复制块。 pickerCompletion
拥有复制块(堆块)的所有权。
@property (weak, nonatomic) void(^pickerCompletion)(NSDate *date);
但是如果属性是weak
,编译器什么都不做,只是把指针值赋给变量。如果指针是 Stack Block(只是普通的块文字),指针值永远不会被 ARC 填零。难道你没有从编译器那里得到警告信息吗?
warning: assigning block literal to a weak property; object will be
released after assignment
此外还有竞争条件。
if (self.pickerCompletion) self.pickerCompletion(self.date);
在多线程环境中,self.pickerCompletion
可以在 if (self.pickerCompletion)
之后的 self.pickerCompletion(self.date)
之前补零。使用临时 __strong
变量来安全访问弱对象。
void(^pickerCompletion)(NSDate *date) = self.pickerCompletion;
if (pickerCompletion) pickerCompletion(self.date);