我遇到的唯一功能差异是我可以取消预定的消息performSelector:withObject:afterDelay:.我不知道取消提交的块的方法dispatch_after.(请告诉我是否有办法做到这一点,我不知道).
我想了解更多:
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",然后崩溃.为什么?
对行为不确定,因为我怀疑我遇到了僵局,
我有一个包含多个对象的类 - 每个对象创建一个具有相同名称的队列.我不确定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) 最近我一直在使用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) 以下是我所了解和理解的事情:
全局队列是一个并发队列,可以将任务分派给多个线程.执行任务的顺序无法保证.例如:
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.
=====我感到困惑和不完全理解=======
主线程有一个NSRunLoop,在主线程中循环任务.我想知道调度队列和运行循环之间的关系是什么?我可以理解它,如果将任务调度到主线程,主线程的NSRunLoop获取调度任务并执行它吗?
将任务分派给多个线程的全局队列怎么样?iOS/OSX系统是否自动创建线程,还为每个线程创建NSRunLoop?然后每个线程中的运行循环从全局队列中获取调度任务并执行它?
谁知道线程?do dispatch_async()和dispatch_sync()function知道哪个线程要调度任务,或者队列知道哪个线程要调度任务?
有没有办法以编程方式从调度队列中获取线程的NSRunLoop对象(调度任务的对象)?(这个问题与问题3有关)
multithreading nsthread grand-central-dispatch nsrunloop ios
在Android上有任务队列吗?我知道它可以手工编写但是有一个可以使用的库吗?
在Apple文档中,它说:
要点:您永远不应该从正在计划传递给该函数的同一队列中执行的任务调用dispatch_sync或dispatch_sync_f函数.这对于保证死锁的串行队列尤其重要,但对于并发队列也应该避免.
你如何编写代码才能做到这一点?
如何创建以高优先级运行的自定义串行队列?
现在我正在使用,myQueue = dispatch_queue_create("com.MyApp.MyQueue", NULL);但这似乎不允许设置优先级?
这可能是一个愚蠢的问题,但我需要为自己提出并清楚这一点.
要将块提交到队列以供执行,请使用函数dispatch_sync和dispatch_async.它们都将队列和块作为参数.dispatch_async立即返回,异步运行块,同时dispatch_sync执行块直到提供的块返回.以下是一些情况:
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)
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)
{
[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)
{
[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
我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)
之前它在控制台中显示消息的原因是什么?