相关疑难解决方法(0)

为什么这个dispatch_sync()调用冻结?

我正在使用Kiwi测试框架在我的应用程序中测试身份验证方法.在调用dispatch_sync时,测试冻结,如下所示:

dispatch_queue_t main = dispatch_get_main_queue();
dispatch_sync(main, ^
                  {
                      [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
                  });
Run Code Online (Sandbox Code Playgroud)

我想知道为什么它冻结在那里,如果有人有任何提示.

multithreading cocoa-touch objective-c grand-central-dispatch

29
推荐指数
2
解决办法
1万
查看次数

我正在运行什么GCD队列,主要与否?

我正在尝试编写一些线程安全的方法,所以我正在使用:

...
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_sync(main,^{
  [self doSomethingInTheForeground];
});
...
Run Code Online (Sandbox Code Playgroud)

但是如果我在主线程上没有必要,我可以跳过所有这些调度调用,所以我想知道我目前正在使用什么线程.我怎么知道这个?

或者,也许它在性能方面没有差别?

可以做这个比较吗?

if (dispatch_get_main_queue() == dispatch_get_current_queue()){...}
Run Code Online (Sandbox Code Playgroud)

cocoa multithreading objective-c grand-central-dispatch

10
推荐指数
2
解决办法
7663
查看次数

如何使用dispatch_queue_set_specific()和dispatch_get_specific()

我很难找到关于如何使用这些功能的好例子.

static void * kQueue1Key = "key1";
static void * kQueue2Key = "key2";

dispatch_queue_t queue1 = dispatch_queue_create("com.company.queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("com.company.queue2", DISPATCH_QUEUE_SERIAL);

dispatch_queue_set_specific(queue1, kQueue1Key, (void *)kQueue1Key, NULL);
dispatch_queue_set_specific(queue2, kQueue2Key, (void *)kQueue2Key, NULL);

dispatch_sync(queue1, ^{
    if(dispatch_get_specific(kQueue1Key))
    {
        NSLog(@"I'm expecting this line to run (A)");

        dispatch_sync(queue2, ^{

            NSLog(@"I'm expecting this line to run (B)");

            if(dispatch_get_specific(kQueue2Key))
            {
                if(dispatch_get_specific(kQueue1Key))
                {
                    NSLog(@"I'm expecting this line to run (C)");
                }
                else
                {
                    [NSException raise:NSInternalInconsistencyException format:@"Should not end up here (C)"];
                }
            }
            else
            {
                [NSException …
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch objective-c-blocks

7
推荐指数
1
解决办法
5266
查看次数

使NSOperation同步

我正在开发一个应用程序,允许用户从iPad上创建云上的文件和文件夹.删除文件后,应用程序会自动在云上创建"回收站"文件夹并将该文件放入其中.我已NSOperationQueue为所有操作创建,即我有单独的文件夹创建队列和单独的文件上载队列.我面临的问题是,文件上传操作在文件夹创建操作完成之前执行,因此文件无法成功上传.

任何人都可以帮助我使文件夹创建操作同步吗?

我试过以下代码

[create_folder_queue addOperations:[NSArray arrayWithObject:folderOperation] waitUntilFinished:YES];
Run Code Online (Sandbox Code Playgroud)

但它不执行操作.

提前致谢.

iphone nsoperation nsoperationqueue ios

4
推荐指数
1
解决办法
6910
查看次数

宏在主线程上运行方法

我想要一种简单的方法来在一个方法的开头删除代码,该方法将强制该方法仅在主线程上运行(因为该方法更新了UI元素).

目前,我有类似的东西:

 if (![NSThread isMainThread]){
    [self performSelectorOnMainThread:_cmd withObject:_results waitUntilDone:NO];
    return;
}
Run Code Online (Sandbox Code Playgroud)

但是我想要一种方法将它包含在一个宏中而不必输入方法的参数.看起来应该有一些方法来迭代传递给当前方法的参数列表并创建一个NSInvocation或类似的.有什么想法吗?

multithreading objective-c ios

4
推荐指数
1
解决办法
1688
查看次数

dispatch_sync中的dispatch_sync导致死锁

我刚刚在objc.io上看到了这完全异步,但找不到好的解释

dispatch_queue_t queueA; // assume we have this
dispatch_sync(queueA, ^(){  // (a)
    dispatch_sync(queueA, ^(){ // (b)
        foo();
    });
});
Run Code Online (Sandbox Code Playgroud)

一旦我们点击了第二个dispatch_sync,我们就会死锁:我们无法调度到queueA,因为有人(当前线程)已经在该队列上并且永远不会离开它.

只要我明白

  1. dispatch_sync只需添加工作项(我避免使用"块",因为它可能会混淆)到queueA,然后这个工作项将被发送到queueA的目标队列,然后GCD将为此工作项保留一个线程 threadWorkItem
  2. 当我到达(b)时,我在线程threadWorkItem(假设threadWorkItem是这个线程的名称),所以我认为将另一个工作项排入队列是没有问题的.但有人说,此时,queueA被保留,queueA被阻止 - >导致死锁,这让我感到困惑

我已经阅读了很多与此相关的线程,比如使用dispatch_sync进行死锁,为什么我们不能在当前队列中使用dispatch_sync?,为什么这个dispatch_sync()调用冻结?,...但是找不到好的解释.有人说dispatch_sync阻止队列,有人说它阻止当前线程,...... :(

那为什么会导致僵局呢?

deadlock sync dispatch grand-central-dispatch ios

4
推荐指数
1
解决办法
2516
查看次数

如何使用GCD在主线程上延迟后安全地调度代码?

如果你已经在主线程上,在主线程上发送延迟代码块是否安全?

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), theBlock);
Run Code Online (Sandbox Code Playgroud)

或者有更安全的方式吗?如果我在执行此操作时已经在主队列(主线程)上,是否必须执行任何检查?

iphone objective-c grand-central-dispatch ipad ios

2
推荐指数
1
解决办法
3277
查看次数

对dispatch_queue,reentrancy和deadlocks的澄清

我需要澄清dispatch_queues与reentrancy和死锁的关系.

在iOS/OS X上阅读此博客帖子Thread Safety Basics时,我遇到了这样一句话:

所有调度队列都是不可重入的,这意味着如果您尝试在当前队列上调度_sync,则会出现死锁.

那么,重入和死锁之间的关系是什么?为什么,如果a dispatch_queue是不可重入的,当您使用dispatch_sync呼叫时会出现死锁?

根据我的理解,dispatch_sync只有当您运行的线程与块发送到的线程相同时,才能使用死锁.

一个简单的例子如下.如果我在主线程中运行代码,因为它dispatch_get_main_queue()也会抓住主线程并且我将以死锁结束.

dispatch_sync(dispatch_get_main_queue(), ^{

    NSLog(@"Deadlock!!!");

});
Run Code Online (Sandbox Code Playgroud)

有任何澄清吗?

macos multithreading deadlock grand-central-dispatch ios

2
推荐指数
1
解决办法
1066
查看次数