ios - 在一组异步 Web 服务调用后使用信号量 token 运行代码时出错

标签 ios objective-c

我处于这样一种情况,我需要一次调用多个 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/

相关文章:

objective-c - 如何制作像 Podcast 应用程序那样的转场效果?

ios - 首先按特定 NSString 对 NSArray 进行排序,然后按字母顺序排序

c++ - 如果应用程序仅为 armv7 和 armv7s 编译,那么在 arm64 设备上运行时它使用什么大小的数据类型?

ios - IBInspectable & watchkit

ios - Firebase 存储下载到本地文件错误

ios - 通过推送通知 Objective C iOS 从 Kill 状态打开时应用程序崩溃

ios - 将 UIImage 转换为 CIImage 时图像大小加倍

ios - 在某些情况下,UIScrollView 中的减速非常慢

ios - MonoTouch 链接器无法解析 System.Void System.Console::set_ForegroundColor(System.ConsoleColor)

ios - 通知中心在两个 View 之间不起作用