私はHTTPリクエストの作成に使用するカスタムNSOperationサブクラスを持っています。 NSOperationが完了したときに実行されるブロックベースのコールバックを受け入れます。それに応じてすべてが機能しますが、完了コールバックを実行しようとすると、間違った断続的なクラッシュが発生します。私は多くのブロックベースのEXEC_BAD_ACCESSの問題は、ブロックを追加のメソッドに渡すときにブロックを正しくコピーしないことが原因であると読んでいます。ブロックコールバックがEXC_BAD_ACCESSでクラッシュする
私の問題は、ブロックをどのように利用しているのかと関係していると思います。下のアプリケーションの標準的な使用例を示します。私の問題の根源は、ブロックが関係している所有権の誤解につながりそうです。
// Perform a HTTP request to a specified endpoint and declare a callback block
[self performRequestToEndpoint:@"endpoint" completion:^(HTTPResponse *response) {
NSLog(@"Completed with response: %@", response);
}];
// A helper function to avoid having to pass around too many parameters
- (void)performRequestWithEndpoint:(NSString *)endpoint completion:(void (^)(HTTPResponse *response))completionBlock
{
// Make our HTTP request and callback our original completion block when done
[self requestWithMethod:@"GET" path:endpoint completion:^(HTTPResponse *response) {
if(![response error])
{
// Call our original completion block
completionBlock(response);
}
];
}
コールバックブロックはrequestWithMethodを介して割り当てられている:パス:終了:方法であって、それはそうようにコピーされています:
@property (nonatomic, copy) void (^operationCompletionBlock)(HTTPResponse *response);
ここクラッシュのポイントは次のとおり
添付- (void)callCompletionBlockWithResponse:(id)response
{
if(self.operationCompletionBlock && !self.isCancelled)
{
self.operationCompletionBlock(response); // crashes here (intermittently)
}
[self finish];
}
以下はスタックトレースです。
* thread #1: tid = 0x2403, 0x0000000000000000, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000000000000
frame #1: 0x00007f946b53ed01
frame #2: 0x0000000102da7cf7 Project`-[HTTPRequest callCompletionBlockWithResponse:] + 215 at HTTPRequest.m:402
frame #3: 0x0000000102da79e7 Project`__44-[HTTPRequest connectionDidFinishLoading:]_block_invoke_0 + 423 at HTTPRequest.m:381
frame #4: 0x00007fff956fea86 libdispatch.dylib`_dispatch_call_block_and_release + 18
frame #5: 0x00007fff957008f6 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 308
frame #6: 0x00007fff8f07ce7c CoreFoundation`__CFRunLoopRun + 1724
frame #7: 0x00007fff8f07c486 CoreFoundation`CFRunLoopRunSpecific + 230
frame #8: 0x00007fff94f1a4d3 HIToolbox`RunCurrentEventLoopInMode + 277
frame #9: 0x00007fff94f21781 HIToolbox`ReceiveNextEventCommon + 355
frame #10: 0x00007fff94f2160e HIToolbox`BlockUntilNextEventMatchingListInMode + 62
frame #11: 0x00000001032a6e31 AppKit`_DPSNextEvent + 659
frame #12: 0x00000001032a6735 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
frame #13: 0x00000001032a3071 AppKit`-[NSApplication run] + 470
frame #14: 0x000000010351f244 AppKit`NSApplicationMain + 867
frame #15: 0x0000000102d69512 Project`main + 34 at main.m:13
frame #16: 0x0000000102d694e4 Project`start + 52
あなたは実際にそれを設定するためにプロパティを使用していますか?例えば'self.operationCompletionBlock = completionBlock;'インスタンス変数に直接設定しませんか?例えば'operationCompletionBlock = completionBlock;' – newacct
うん!これはあなたが 'self.operationCompletionBlock = completionBlock; 'と全く同じように設定されています。 – ndg
間違っているものは見えません。おそらく、あなたはrequestWithMethod:path:completion:メソッド – newacct