如何创建以高优先级运行的自定义串行队列?
现在我正在使用,myQueue = dispatch_queue_create("com.MyApp.MyQueue", NULL);但这似乎不允许设置优先级?
在最近学习了Grand Central Dispatch之后,我发现多线程代码非常直观(使用GCD).我喜欢这样一个事实,即不需要锁(事实上它在内部使用无锁数据结构),并且API非常简单.
现在,我开始学习pthreads,我不禁对复杂性感到不知所措.线程连接,互斥体,条件变量 - 所有这些事情在GCD中都不是必需的,但在pthreads中有很多API调用.
pthreads是否比GCD有任何优势?它效率更高吗?是否存在正常使用情况,其中pthreads可以执行GCD无法执行的操作(不包括内核级软件)?
在跨平台兼容性方面,我并不太关心.毕竟,libdispatch是开源的,Apple已经将其关闭更改作为GCC的补丁,clang支持关闭,并且已经(从FreeBSD开始),我们开始看到一些非Apple的GCD实现.我最感兴趣的是使用API(具体的例子会很棒!).
我正在使用dispatch_queue,它通过其所有者的属性访问,如下所示:
@property (nonatomic, assign) dispatch_queue_t queue;
Run Code Online (Sandbox Code Playgroud)
注意assign关键字.队列在整个对象生命周期中使用,因此由对象拥有.我取消分配拥有对象时释放队列:
-(void)dealloc
{
dispatch_release(self.queue);
self.queue = nil;
}
Run Code Online (Sandbox Code Playgroud)
我该如何正确发布?会用到retain/release工作吗?
如果在调用release时队列中有待处理/正在运行的东西,会发生什么?
我为NSThread和Grand Central Dispatch(GCD)创建了一些测试代码:
- (void)doIt:(NSNumber *)i
{
sleep(1);
NSLog(@"Thread#%i", [i intValue]);
}
- (IBAction)doWork:(id)sender
{
for (int i = 0; 10 > i; i++) {
NSNumber *t = [NSNumber numberWithInt:i];
[NSThread detachNewThreadSelector:@selector(doIt:) toTarget:self withObject:t];
}
sleep(1);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t i) {
sleep(1);
NSLog(@"GCD#%u",(int)i);
});
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
2011-04-13 19:41:07.806 GDC[1494:5e03] Thread#0
2011-04-13 19:41:07.813 GDC[1494:6903] Thread#3
2011-04-13 19:41:07.812 GDC[1494:6403] Thread#2
2011-04-13 19:41:07.812 GDC[1494:5f03] Thread#1
2011-04-13 19:41:07.813 GDC[1494:6e03] Thread#4
2011-04-13 19:41:07.814 GDC[1494:7303] Thread#5
2011-04-13 19:41:07.814 GDC[1494:7803] Thread#6
2011-04-13 …Run Code Online (Sandbox Code Playgroud) 我一直在搜索关于应用程序状态和Grand Central Dispatch的Apple文档,但我没有找到这个问题的好答案.
根据Apple的文档,在iOS 4.0上:
应用程序在后台但不执行代码.系统会在适当的时间自动将应用程序移动到此状态.暂停时,应用程序基本上在其当前状态下冻干,并且不执行任何代码.在内存不足的情况下,系统可能会清除已暂停的应用程序,恕不另行通知,以便为前台应用程序腾出更多空
因此,假设系统没有清除挂起的应用程序(挂起 - >未运行转换),当前在调度队列中执行的任务会发生什么?短语"基本上冻干"还有很多不足之处 - 究竟什么是冷冻干燥的?
我的解释是当应用程序转换回活动状态时,应用程序在暂停时使用的GCD队列需要恢复; 根据这种解释,暂停前GCD队列中存在的任务将消失.我的解释是否正确?
我想知道为什么当你在GCD块中创建一个重复计时器时它不起作用?
这很好用:
-(void)viewDidLoad{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
}
-(void)runTimer{
NSLog(@"hi");
}
Run Code Online (Sandbox Code Playgroud)
但这项工作:
dispatch_queue_t myQueue;
-(void)viewDidLoad{
[super viewDidLoad];
myQueue = dispatch_queue_create("someDescription", NULL);
dispatch_async(myQueue, ^{
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
});
}
-(void)runTimer{
NSLog(@"hi");
}
Run Code Online (Sandbox Code Playgroud) 有人可以帮我解决这个问题吗?
我的UITableViewCell textLabel在我滚动或触摸之前不会更新.
该视图控制器负载,它显示了细胞的适量.但内容是空白的.我必须触摸它或滚动才能显示我的textLabel.
我在这里做错了吗?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setFont: [UIFont systemFontOfSize: 32.0]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDictionary * data = [self timeForObject: [self.months objectAtIndex:indexPath.row]];
dispatch_async(dispatch_get_main_queue(), ^{
NSString *time = [data objectForKey:@"Time"];
NSString *totalTime = [data objectForKey:@"Total Time"];
NSString * textLabel = [NSString stringWithFormat:@" …Run Code Online (Sandbox Code Playgroud) 我声明了一个属性来引用GCD队列:
@property (assign) dispatch_queue_t backgroundQueue;
Run Code Online (Sandbox Code Playgroud)
在类的init方法中,我创建了一个串行队列:
backgroundQueue = dispatch_queue_create("com.company.app", DISPATCH_QUEUE_SERIAL);
Run Code Online (Sandbox Code Playgroud)
ARC抱怨:"将保留对象分配给unsafe_unretained变量;对象将在分配后释放"
我必须使用__bridge_transfer吗?
在-dealloc我发布队列:
dispatch_release(backgroundQueue);
Run Code Online (Sandbox Code Playgroud)
ARC再次提出抱怨:"ARC禁止发布'发布'的明确消息"
我发现这令人困惑,因为这是一个C函数调用,思想队列是C对象,我必须自己处理内存管理!从什么时候开始为我处理C-objects?
memory-management grand-central-dispatch ios automatic-ref-counting
我试图了解Grand Central Dispatch的概念.我想理解Vandad关于并发编程的书中的这些引用.
GCD的真正用途是将任务分配给多个内核,而不是让您成为程序员,而是担心哪个内核正在执行哪个任务.
和
GCD的核心是调度队列.调度队列是线程池.
最后
您不会直接使用这些线程.您将只使用调度队列,将任务分派给这些队列并要求队列调用您的任务.
我加粗了关键术语.
多个核心与队列相同吗?队列是否包含许多线程?每个线程都执行任务吗?
我有几个单元测试,我想测试是否在正确的调度队列上调用了回调.
在Swift 2中,我将当前队列的标签与我的测试队列进行了比较.但是在Swift 3中,DISPATCH_CURRENT_QUEUE_LABEL常量不再存在.
我确实找到了这个dispatch_assert_queue功能.这似乎是我需要的,但我不知道如何称呼它.
我的Swift 2代码:
let testQueueLabel = "com.example.my-test-queue"
let testQueue = dispatch_queue_create(testQueueLabel, nil)
let currentQueueLabel = String(UTF8String: dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))!
XCTAssertEqual(currentQueueLabel, testQueueLabel, "callback should be called on specified queue")
Run Code Online (Sandbox Code Playgroud)
更新:
我对缺乏自动完成感到困惑,但可以使用__dispatch_assert_queue:
if #available(iOS 10.0, *) {
__dispatch_assert_queue(test1Queue)
}
Run Code Online (Sandbox Code Playgroud)
虽然这确实适用于单元测试,但它会烦人地停止整个过程EXC_BAD_INSTRUCTION而不是仅仅测试失败.
ios ×5
objective-c ×5
cocoa-touch ×1
macos ×1
nsrunloop ×1
nsthread ×1
nstimer ×1
pthreads ×1
queue ×1
swift ×1
swift3 ×1
terminology ×1
uitableview ×1