Objective c 多个调度组导致崩溃

Objective c 多个调度组导致崩溃,objective-c,grand-central-dispatch,Objective C,Grand Central Dispatch,所以我有一个函数,在for循环中执行一些异步任务,所以我添加了一个调度组,一切正常 dispatch_group_t group = dispatch_group_create(); for(apple in fruits) { dispatch_group_enter(group); [self randomFunction:^{ dispatch_group_leave(group); }]; };

所以我有一个函数,在for循环中执行一些异步任务,所以我添加了一个调度组,一切正常

dispatch_group_t group = dispatch_group_create();

for(apple in fruits) {
    dispatch_group_enter(group);
    [self randomFunction:^{
                   dispatch_group_leave(group);
               }];
   
};
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
   //some tasks
    }];
});

randomFunction:(void(^)(void)completionhandler{
//do pushups
completionhandler();
}
问题在于,当当前循环运行第二个代码时,可以从不同的流调用random函数

dispatch_group_t group2 = dispatch_group_create();

for(candies in sweets) {
    dispatch_group_enter(group2);
    [self randomFunction:^{
                   dispatch_group_leave(group2);
               }];
   
};
dispatch_group_notify(group2, dispatch_get_main_queue(), ^{
   //some tasks
    }];
});

function:(void(^)(void)completionhandler{
//do jumping jacks
 completionhandler();
}

当两个流同时触发时,应用程序崩溃,LIBDISPATCH:dispatch\u group\u leave()的客户端出现错误。我检查了double/tripple,没有不平衡的dipatch_group_leave()调用,只要一次只调用一个流,代码就可以正常工作。据我所知,我认为1个案例的group.leave()消耗了该组。另一个案例的enter()消耗了该组,并将计数减到零以下,但如果发生这种情况,这两个组是不同的?

在进入和离开一个组时,输入一些
NSLog()
调用,看看哪里出了问题。每个组都是独立的,这是正确的,所以这不是问题所在。上面的代码显然不是您的实际代码(因为它甚至不接近有效的ObjC)。在某些地方,您的实际代码具有不平衡的调用。我同意koen的观点,NSLog可能是找到它所在位置的最佳选择。仅仅查看代码可能不会为您找到它;您需要运行它并查看在哪里调用了您不希望被调用的东西。(你认为正确的东西是不正确的。这就是错误所在。)我同意@RobNapier的观点,这些类型或问题/崩溃通常与不平衡或无序的
dispatch\u group\u enter()
/
dispatch\u group\u leave()
配对有关。考虑使用“代码> >尝试{}”最终{ < /C> >以捕捉代码可能抛出的任何异常,并确保在每种情况下调用<代码> DeXCHYGROMPULYAVE()/Cult>。请记住,<代码> @尝试< /Cord>可能有助于发现错误(例如,在崩溃之前添加更好的日志记录)。,它不是生产解决方案。Cocoa不是异常安全的,并且除非您使用
-fobjc ARC exceptions
构建,否则ObjC try/catch故意不在ARC下正确管理内存(ObjC++默认启用此选项)。即使使用该标志,弱对象也会因设计而泄漏。通常情况下,编写异常安全的ObjC代码是不实际的,也不是有意的。重申一下其他人所说的,问题不在于您有两个不同的调度组同时进行。问题只在于其中一个或另一个(或两者都有)您调用
leave
的次数比调用
enter
的次数多。您的函数必须具有某种执行路径,其中您多次调用完成处理程序。