我处于这样一种情况,我需要一次调用多个 Web 服务请求来调用我的服务器以删除服务器上的消息,我很难找出触发某些方法的最佳方法在完成这组 Web 服务调用时刷新我的数据。
根据我的研究,使用信号量计数器应该可以满足我想做的事情,但我遇到了一个问题,即在我的信号量 token 上调用 dispatch_release() 时,我的应用程序因此崩溃 -
libdispatch.dylib`_dispatch_semaphore_dispose$VARIANT$mp:
0x3c03ed70: push {r7, lr}
0x3c03ed72: ldr r1, [r0, #40]
0x3c03ed74: mov r7, sp
0x3c03ed76: ldr r2, [r0, #36]
0x3c03ed78: cmp r1, r2
0x3c03ed7a: bge 0x3c03ed7e ; _dispatch_semaphore_dispose$VARIANT$mp + 14
0x3c03ed7c: trap
我在这个问题上发现的一切都指向信号量 token 被某物引用,但我看不到什么会引用该 token 。
- (void)deleteMultipleThreadsForMessages:(NSArray *)messages withCompletion:(void(^)(BOOL allThreadsDeleted))completion
{
NSDictionary *userDictionary = [[MSMKeychainAccess sharedKeychain] returnUserDictionary];
long messagesCount = [messages count] - 1;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(messagesCount);
BOOL (^isLastRequest)(void) = ^BOOL (void) {
long result = dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW);
if (0 == result) {
return false;
}
dispatch_release(semaphore);
return true;
};
for (MSMMessageDataModel *message in messages) {
NSDictionary *dictionary = @{@"license": userDictionary[@"license"],
@"messageID" : message.msgID};
NSLog(@"Called this many times! %@", message.msgID);
[[MSMClient sharedClient] soapPostsWithCompletion:^(NSDictionary *response, NSError *error) {
if (error) {
isLastRequest();
completion(NO);
} else {
if (isLastRequest()) {
completion(YES);
}
}
} andRequest:[[[MSMRequestsController alloc] init] createGetMessagesSOAPCallAndSendRequest:@"DeleteThread"
withParameters:dictionary]];
}
}
编辑
感谢您的精彩回答。正如 Dustin 所说,我试图将 dispatch_semaphore 用于它不应该用于的事情。我接受了他的回答,因为它实现起来很简单,并且不需要对我目前正在做的事情进行任何重组来发送我的网络服务。不过,我现在有了一些关于 dispatch_groups 的很好的阅读 Material !
感谢您的帮助!
最佳答案
我不确定这是解决您问题的最有效方法,但只要查看您的代码,您可能会遇到的一个问题是您正在创建带有计数的信号量并尝试在以下时间释放它该计数小于初始计数。在 GCD 中,始终使用 0 创建一个信号量,然后将信号量发送给您需要计数的正确数量的“资源”。原因是因为如果信号量的计数小于初始计数,则无法销毁/释放信号量。如果您将其视为资源计数器,这有点有意义。信号量编号小于初始计数意味着您有一个工作人员仍在使用其中一个资源。
你可以在这里看到这段代码 http://opensource.apple.com/source/libdispatch/libdispatch-187.7/src/semaphore.c . _dispatch_semaphore_dispose
中会抛出异常的代码是:
if (dsema->dsema_value < dsema->dsema_orig) {
DISPATCH_CLIENT_CRASH(
"Semaphore/group object deallocated while in use");
}
关于ios - 在一组异步 Web 服务调用后使用信号量 token 运行代码时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16927374/