堆栈跟踪中的方法显示为从块中调用,但在代码中并非如此

Method in stack trace is shown to be invoked from block, while it is not true in code

我有 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 的堆栈跟踪,我目前正在调查这个问题。然而,最让我惊讶的是堆栈跟踪显示块调用,而方法不是从块调用而是从 URLSession 委托方法调用。

    Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x1814d01a0 objc_retain + 16
1  libobjc.A.dylib                0x1814d0218 objc_storeStrong + 44
2  App                        0x1004644e8 -[FCProgressIndicator animateProgressViewToProgress:] (FCProgressIndicator.m:85)
3  App                        0x10046a560 -[FCSeriesListCollectionViewCell updateForItem:] (FCSeriesListCollectionViewCell.m:156)
4  App                        0x1003da4a8 __54-[FCFilmDownloadService notifyListenersForItemUpdate:]_block_invoke (FCFilmDownloadService.m:295)
5  libdispatch.dylib              0x181becaa0 _dispatch_call_block_and_release + 24
6  libdispatch.dylib              0x181beca60 _dispatch_client_callout + 16
7  libdispatch.dylib              0x181bf965c _dispatch_main_queue_callback_4CF$VARIANT$mp + 1012
8  CoreFoundation                 0x1822a3070 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
9  CoreFoundation                 0x1822a0bc8 __CFRunLoopRun + 2272
10 CoreFoundation                 0x1821c0da8 CFRunLoopRunSpecific + 552
11 GraphicsServices               0x1841a6020 GSEventRunModal + 100
12 UIKit                          0x18c1e0758 UIApplicationMain + 236
13 App                        0x1004a707c main (main.m:14)
14 libdyld.dylib                  0x181c51fc0 start + 4

实际代码是:

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {

    NSString *downloadUrl = downloadTask.originalRequest.URL.absoluteString;
    FCDownloadableFilm *item = self.downloads[downloadUrl];

    /*Processing data */

    [self notifyListenersForItemUpdate:item];
}

- (void)notifyListenersForItemUpdate:(FCDownloadableFilm *) item {

    dispatch_async(dispatch_get_main_queue(), ^{
        NSSet *listeners = [self.listeners[item.url] copy];
        for (id <FCFilmDownloadServiceProtocol> listener in listeners) {
            [listener updateForItem: item];
        }
    });
}

什么会导致堆栈跟踪显示方法 notifyListenersForItemUpdate 是从块中调用的,而实际上不是?

堆栈跟踪未显示 notifyListenersForItemUpdate 已从块中调用。这是从 notifyListenersForItemUpdate:

中的块调用的 updateForItem 的跟踪
dispatch_async(dispatch_get_main_queue(), ^{

(这个)

堆栈跟踪表明正在处理一个主循环,其中有一个在 [FCFilmDownloadService notifyListenersForItemUpdate:] 中声明的块。