objc函数传参时关键字的一个细节
objc函数的形参,默认加关键字__autoreleasing
//如NSError对象常见的传参方式
NSError* error;
[self test__xxx:&error];
- (void)test__xxx:(NSError**)error
{
//未加任何关键字时编译器默认判定为__autoreleasing
*error = [NSError errorWithDomain:@"error" code:0 userInfo:nil];
//编译器判定需要引用该临时变量,对临时变量引用计数器+1。使得该临时变量不会被释放
}
大部分情况不需要去注意形参关键字,但是下面一种情况下需要考虑
- (void)test__xxx:(NSError**)error
{
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
*error = [NSError errorWithDomain:@"error" code:0 userInfo:nil];
//随后指向的临时变量被释放了
//编译器判定__autoreleasing在该block作用域内不需要强引用,没有操作引用计数器
}];
//这里访问error程序会崩溃
//通常block对之外的参数传值是需要使用__block的,但是形参上不能使用该关键字
}
遇到这种情况应该在形参上使用关键字__strong明确告知编译器该形参指向的对象全部进行强引用
- (void)test__xxx:(NSError*__strong*)error
{
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
*error = [NSError errorWithDomain:@"error" code:0 userInfo:nil];
//编译器判定需要引用该临时变量,对临时变量引用计数器+1
}];
}