自動参照カウントを使用して、プロジェクトのブロック内から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];
}];
}
これはコンパイルされますが、変更するブロックのローカルNSErrorを作成しようとすると、変更される可能性があります。これは、列挙後に元のNSErrorを設定するために使用されerror
ます
(これは表示していません)。doSomethingWithItem
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パラメータに渡して書き戻す
このエラーをグーグルで検索すると、Clangソースコード自体からの結果のみが返されます。
動作しているように見えますが、少し醜い解決策の1つは、内部および外部のエラーポインタを用意することです。
- (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を設定する正しい方法は何ですか?