我希望在项目的块中使用设置NSError指针 自动参考计数。以下是我的代码的简化版本:
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
[blockSelf doSomethingWithItem:item error:error];
}];
}
这个编译,但给定error
可能会被修改
doSomethingWithItem
我尝试为块创建一个本地NSError
修改,然后用于设置原始error
之后
枚举(我没有显示):
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
__block NSError *blockError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
[blockSelf doSomethingWithItem:item error:&blockError];
}];
}
无法使用以下错误进行编译:
将非本地对象的地址传递给__autoreleasing参数以进行回写
Google搜索此错误只会返回Clang源代码本身的结果。
一个似乎有用但有点难看的解决方案是有一个内部和外部错误指针:
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
__block NSError *outerError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
NSError *innerError = nil;
[blockSelf doSomethingWithItem:item error:&innerError];
outerError = innerError;
}];
}
在块中设置NSError的正确方法是什么?
答案 0 :(得分:8)
试试这个:
// ...
__block NSError *blockError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
NSError *localError = nil;
if (![blockSelf doSomethingWithItem:item error:&localError]) {
blockError = localError;
}
}];
// ...
至于为什么这是必要的,我仍然试图掌握这一点。当我这样做时,我会更新这个答案。 :)
答案 1 :(得分:1)
在块中设置NSError的正确方法是什么?
如" What's new in LLVM?" @ 14:55,有两种技术可以解决NSError的问题,它隐式自动释放。
最简单的解决方法是使用__strong
- (BOOL)frobnicateReturningError:(NSError *__strong *)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
NSError *innerError = nil;
[blockSelf doSomethingWithItem:item error:&innerError];
if(innerError && error) {
*error = [NSError errorWithDomain:...];
}
}];
}
第二个修复是使用__block
- (BOOL)frobnicateReturningError:(NSError **)error
{
NSArray *items = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
__block Frobnicator *blockSelf = self;
__block NSError *strongError = nil;
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
NSError *innerError = nil;
[blockSelf doSomethingWithItem:item error:&innerError];
if(innerError) {
strongError = [NSError errorWithDomain:...];
}
}];
if (error) *error = strongError;
}