Блокировка обратного вызова с ошибкой EXC _BAD _ACCESS

У меня есть собственный подкласс NSOperation, который я использую для выполнения HTTP-запросов. Он принимает обратный вызов на основе блока -, который выполняется после завершения NSOperation. Все работает соответственно, но я испытываю странный прерывистый сбой при попытке выполнить обратный вызов завершения. Я прочитал много блоков -на основе EXEC _BAD _Проблемы с доступом вызваны неправильным копированием блока при передаче его дополнительным методам.

Я считаю, что моя проблема связана с тем, как я использую блоки. Ниже я приведу стандартный вариант использования для своего приложения. Корень моей проблемы, вероятно, сводится к неправильному пониманию прав собственности, когда речь идет о блоках.

// 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
6
задан ndg 26 July 2012 в 08:19
поделиться