首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >libobjc.A.dylib objc_msgSend崩溃是在后台线程中使用核心数据发生的

libobjc.A.dylib objc_msgSend崩溃是在后台线程中使用核心数据发生的
EN

Stack Overflow用户
提问于 2016-08-02 03:29:54
回答 1查看 841关注 0票数 0

我正在调查应用程序的Crashlytics控制台中经常报告的一次崩溃。

我有许多示例之一,其中有以下崩溃的线程堆栈跟踪:

代码语言:javascript
运行
复制
#11. Crashed: com.apple.root.default-qos
0  libobjc.A.dylib                0x22f3fa86 objc_msgSend + 5
1  Foundation                     0x23ee3005 -[NSString caseInsensitiveCompare:] + 28
2  Foundation                     0x23ed10bd _NSCompareObject + 28
3  Foundation                     0x23ed109d _NSSortFunctionOne + 120
4  CoreFoundation                 0x2373e6a3 __CFSimpleMergeSort + 114
5  CoreFoundation                 0x2373e6c5 __CFSimpleMergeSort + 148
6  CoreFoundation                 0x2373e6d9 __CFSimpleMergeSort + 168
7  CoreFoundation                 0x2373e6c5 __CFSimpleMergeSort + 148
8  CoreFoundation                 0x2373e6d9 __CFSimpleMergeSort + 168
9  CoreFoundation                 0x2368ac35 CFSortIndexes + 404
10 CoreFoundation                 0x2368c241 CFMergeSortArray + 176
11 Foundation                     0x23ed0a9d _sortedObjectsUsingDescriptors + 456
12 Foundation                     0x23f9c9fb -[NSSet(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 510
13 MyApp                          0x6d431 __24-[MyApp refresh]_block_invoke (MyApp.m:247)
14 CoreFoundation                 0x23769499 __NSArrayEnumerate + 372
15 CoreFoundation                 0x236e6c3b -[NSArray enumerateObjectsWithOptions:usingBlock:] + 62
16 MyApp                          0x6d17d -[MyApp refresh] (MyApp.m:263)
17 MyApp                          0xa97eb __52-[MyAppRequest updateAfterNotification:]_block_invoke (MyAppRequest.m:1175)
18 libdispatch.dylib              0x23307cbf _dispatch_call_block_and_release + 10
19 libdispatch.dylib              0x233136a1 _dispatch_root_queue_drain + 1572
20 libdispatch.dylib              0x2331307b _dispatch_worker_thread3 + 94
21 libsystem_pthread.dylib        0x234a6e0d _pthread_wqthread + 1024
22 libsystem_pthread.dylib        0x234a69fc start_wqthread + 8

崩溃的其他实例发生在相同的应用程序代码中(在refresh方法的MyApp类中),但发生在CoreFoundation sortedArrayUsingDescriptors方法逻辑的不同部分。例如,堆栈跟踪的另一个崩溃示例有:

代码语言:javascript
运行
复制
0  libobjc.A.dylib                0x1823cdb90 objc_msgSend + 16
1  CoreFoundation                 0x182c42738 CFStringCompareWithOptionsAndLocale + 232
2  Foundation                     0x183644840 _NSCompareObject + 64
3  CoreFoundation                 0x182d150f4 __CFSimpleMergeSort + 196
4  CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
5  CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
6  CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
7  CoreFoundation                 0x182d1513c __CFSimpleMergeSort + 268
8  CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
9  CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
10 CoreFoundation                 0x182d15124 __CFSimpleMergeSort + 244
11 CoreFoundation                 0x182c3b738 CFSortIndexes + 472
12 CoreFoundation                 0x182c3cf58 CFMergeSortArray + 220
13 Foundation                     0x1836440f8 _sortedObjectsUsingDescriptors + 564
14 Foundation                     0x183725120 -[NSSet(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 564
15 MyApp                          0x10006f264 __24-[MyApp refresh]_block_invoke (MyApp.m:247)

刷新中的应用程序代码是:

代码语言:javascript
运行
复制
- (void)refresh {
    NSArray *products = [self getProducts];
    NSMutableArray *validProducts = [NSMutableArray array];
    [products enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        Product *prod = obj;

        // Convert to internal native format (MyAppProduct) for business reasons...
        MyAppProduct *myAppProd = [[MyAppProduct alloc] init];
        myAppProd.ID = prod.id;
        myAppProd.name = prod.name;

        NSArray *subProds = [prod.subProds sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"subProds" ascending:NO]]];
        NSMutableArray *validSubProds = [NSMutableArray array];
        [subProds enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SubProd *subProd = obj;

            // Convert to internal native format (MyAppSubProduct) for business reasons...
            MyAppSubProduct *myAppSubProd = [[MyAppSubProduct alloc] initWithSubProd:subProd];
            [validSubProds addObject:myAppSubProd];
        }];
        myAppProd.subProds = validSubProds;
        myAppProd.count = [product.count integerValue];

        // Add to array
        [validProducts addObject:myAppProd];
    }];

    // Apply array to self
    _products = validProducts
}

其中getProducts是:

代码语言:javascript
运行
复制
- (NSArray*)getProducts {
    NSFetchRequest *productFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Products"];

    // Filter
    NSMutableArray *productsPredicates = [NSMutableArray array];
    [productsPredicates addObject:[NSPredicate predicateWithFormat:@"life_uid == %@", req.lifeUid]];
    [productsPredicates addObject:[NSPredicate predicateWithFormat:@"hidden == %@", @NO]];
    [productFetchRequest setPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:productsPredicates]];

    // Sort
    NSSortDescriptor *sortProductsByName = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    [productFetchRequest setSortDescriptors:@[sortProductsByName]];

    [productFetchRequest setReturnsObjectsAsFaults:NO];
    [productFetchRequest setRelationshipKeyPathsForPrefetching:@[@"subprods", @"subprods.special"]];

    NSManagedObjectContext *moc = [MyAppCoreDataController sharedController].mainManagedObjectContext;
    NSError *error = nil;
    NSArray *products = [moc executeFetchRequest:productFetchRequest error:&error];
    if (error) {
        NSLog(@"Error fetching products %@", error);
    }
    return products;
}

refresh是这样调用的:

代码语言:javascript
运行
复制
- (void)updateAfterNotification:(NSNotification *)notification {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [[MyApp instance] refresh];
    });
}
EN

回答 1

Stack Overflow用户

发布于 2016-08-02 16:29:45

很可能是因为您没有正确地处理核心数据并发性。使用NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType创建托管对象上下文时,必须将所有的核心数据访问放入对performBlockperformBlockAndWait的调用中。这包括获取以及访问获取对象的属性值。

您正在使用dispatch_async,这不是处理与核心数据并发的正确方法。您应该改用performBlockperformBlockAndWait

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38711332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档