标签: grand-central-dispatch

performSelector:withObject:afterDelay:和dispatch_after之间有什么权衡

我遇到的唯一功能差异是我可以取消预定的消息performSelector:withObject:afterDelay:.我不知道取消提交的块的方法dispatch_after.(请告诉我是否有办法做到这一点,我不知道).

我想了解更多:

  • 功能权衡(一个接口可以实现什么,而另一个接口不能实现?)
  • 性能权衡(一种实现更有效吗?在哪些情况下?)
  • 风格权衡(我是否更喜欢某个任务的界面,以更好地遵循常见的风格或约定?)

iphone objective-c grand-central-dispatch ios4 ios

21
推荐指数
1
解决办法
7074
查看次数

为什么此代码会导致"EXC_BAD_INSTRUCTION"?

dispatch_semaphore_t aSemaphore = dispatch_semaphore_create(1);        
dispatch_semaphore_wait(aSemaphore, DISPATCH_TIME_FOREVER);
dispatch_release(aSemaphore);
Run Code Online (Sandbox Code Playgroud)

当程序运行到dispatch_release(aSemaphore)时,它将导致"EXC_BAD_INSTRUCTION",然后崩溃.为什么?

iphone grand-central-dispatch ios

21
推荐指数
3
解决办法
1万
查看次数

创建具有相同名称的串行队列的2个对象共享同一队列

对行为不确定,因为我怀疑我遇到了僵局,

我有一个包含多个对象的类 - 每个对象创建一个具有相同名称的队列.我不确定GCD是否在对象之间重用相同的队列,或者它们是否只是共享相同的名称.

例如

@interface MyClass

-(void)doSomeWork
@property (nonatomic,strong) dispatch_queue_t myQueue;

@end

@implementation MyClass

-(id)init
{
  self = [super init];
  self.myQueue = dispatch_queue_create("MyQueue",DISPATCH_QUEUE_SERIAL);
  return self;
}

-(void)doSomeWork
{
  dispatch_async(self.myQueue,^{
    // some long running work
  });
}

@end


@interface SomeClassWhichCreatesALotOfObjects

@end


@implementation SomeClassWhichCreatesALotOfObjects

-(void)someMethod
{
  for(int i = 0; i < 10000; i++)
  {
    MyClass *object = [MyClass new];
    [object doSomeWork]; // are these running in serial to each other or are each offset to the queue their object has …
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch ios

21
推荐指数
2
解决办法
5215
查看次数

您是否注意到dispatch_after在iOS设备上运行速度太慢〜10%?

最近我一直在使用dispatch_after而不是performSelector:withObject:afterDelay,当我想在延迟后触发一些代码.代码更清晰,它可以访问封闭的范围,我可以将代码放入内联而不是写一个抛弃方法等等.

我的代码可能如下所示:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * NSEC_PER_SEC),
  dispatch_get_main_queue(),
  ^{
    //Delayed-execution code goes here.
  }
);
Run Code Online (Sandbox Code Playgroud)

但是,我最近发现这段代码的执行时间似乎比请求的速度慢了大约10%.如果我要求延迟10秒,我的块将在11秒后执行.这是在iOS设备上.时间似乎在模拟器上非常接近.

我用来测试它的代码非常简单:

NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * NSEC_PER_SEC),
  dispatch_get_main_queue(),
  ^{
    NSTimeInterval actualDelay = [NSDate timeIntervalSinceReferenceDate] - startTime;
    NSLog(@"Requested delay = %.3f. Atual delay = %.3f", delay, actualDelay);
    //Delayed-execution code goes here.
  }
);
Run Code Online (Sandbox Code Playgroud)

我已经在从iOS 4S到iPad Air的设备上进行了测试,而且额外的延迟非常一致.我还没有在像iPhone 4或iPad 2这样的旧设备上进行测试,尽管我很快就会这样做.

我可能期望在延迟中有20-50毫秒的"斜率",但是一致的10% - 11%的超调是奇怪的.

我在我的代码中添加了一个"软糖因子"来调整额外的延迟,但我发现它令人惊讶:

#define  delay_fudge 0.912557 //Value calculated based on averages from testing.


NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
  delay * delay_fudge *  NSEC_PER_SEC), …
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch ios objective-c-blocks

21
推荐指数
1
解决办法
3832
查看次数

需要对调度队列,线程和NSRunLoop做一些澄清

以下是我所了解和理解的事情:

全局队列是一个并发队列,可以将任务分派给多个线程.执行任务的顺序无法保证.例如:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {
 for (int i; i<10; i++) {
  doTask()
 }
})
Run Code Online (Sandbox Code Playgroud)

如果我想调度到串口队列,我可以使用

dispatch_async(dispatch_queue_create("my.serial.queue", nil) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

每次只有一个任务被分派到一个线程并被执行.订单是FIFO.

=====我感到困惑和不完全理解=======

  1. 主线程有一个NSRunLoop,在主线程中循环任务.我想知道调度队列和运行循环之间的关系是什么?我可以理解它,如果将任务调度到主线程,主线程的NSRunLoop获取调度任务并执行它吗?

  2. 将任务分派给多个线程的全局队列怎么样?iOS/OSX系统是否自动创建线程,还为每个线程创建NSRunLoop?然后每个线程中的运行循环从全局队列中获取调度任务并执行它?

  3. 谁知道线程?do dispatch_async()dispatch_sync()function知道哪个线程要调度任务,或者队列知道哪个线程要调度任务?

  4. 有没有办法以编程方式从调度队列中获取线程的NSRunLoop对象(调度任务的对象)?(这个问题与问题3有关)

multithreading nsthread grand-central-dispatch nsrunloop ios

21
推荐指数
2
解决办法
7698
查看次数

Android上的任务队列就像iOS上的GCD一样?

在Android上有任务队列吗?我知道它可以手工编写但是有一个可以使用的库吗?

multithreading android grand-central-dispatch ios

20
推荐指数
2
解决办法
9285
查看次数

如何在Grand Central Dispatch中创建死锁?

在Apple文档中,它说:

要点:您永远不应该从正在计划传递给该函数的同一队列中执行的任务调用dispatch_sync或dispatch_sync_f函数.这对于保证死锁的串行队列尤其重要,但对于并发队列也应该避免.

你如何编写代码才能做到这一点?

xcode objective-c grand-central-dispatch ios

20
推荐指数
6
解决办法
1万
查看次数

使用GCD创建高优先级串行调度队列

如何创建以高优先级运行的自定义串行队列?

现在我正在使用,myQueue = dispatch_queue_create("com.MyApp.MyQueue", NULL);但这似乎不允许设置优先级?

macos objective-c grand-central-dispatch

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

如果我嵌套了dispatch_async调用,会发生什么?

这可能是一个愚蠢的问题,但我需要为自己提出并清楚这一点.

要将块提交到队列以供执行,请使用函数dispatch_syncdispatch_async.它们都将队列和块作为参数.dispatch_async立即返回,异步运行块,同时dispatch_sync执行块直到提供的块返回.以下是一些情况:

情况1

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"this is statement1");

    });
});
Run Code Online (Sandbox Code Playgroud)

情况2

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"this is statement1");

    });
});
Run Code Online (Sandbox Code Playgroud)

情况3

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_async(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_sync(queue, ^{
            NSLog(@"this is statement1");

        });
    });
Run Code Online (Sandbox Code Playgroud)

情况4

{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);    
    dispatch_sync(queue, ^{
        [self goDoSomethingLongAndInvolved];
        dispatch_async(queue, ^{
            NSLog(@"this …
Run Code Online (Sandbox Code Playgroud)

iphone objective-c grand-central-dispatch ios objective-c-blocks

20
推荐指数
1
解决办法
5304
查看次数

DispatchQueue:在非主线程上无法使用asCopy = NO调用

UIAlertController将主线程呈现为:

class HelperMethodClass: NSObject {

    class func showAlertMessage(message:String, viewController: UIViewController) {
        let alertMessage = UIAlertController(title: "", message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Ok", style: .cancel)

        alertMessage.addAction(cancelAction)

        DispatchQueue.main.async {
            viewController.present(alertMessage, animated: true, completion: nil)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我从任何方面调用方法UIViewController:

HelperMethodClass.showAlertMessage(message: "Any Message", viewController: self)
Run Code Online (Sandbox Code Playgroud)

我正确地得到了输出.

但在控制台中,我收到以下消息:

[Assert]在非主线程上无法使用asCopy = NO调用.

我在这里做错了什么,或者我可以忽略这个消息?

编辑

感谢@NicolasMiari:

添加以下代码不会显示任何消息:

DispatchQueue.main.async {
    HelperMethodClass.showAlertMessage(message: "Any Message", viewController: self)
}
Run Code Online (Sandbox Code Playgroud)

之前它在控制台中显示消息的原因是什么?

grand-central-dispatch swift dispatch-queue swift4.2

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