我有一个可能来自任何线程的回调.当我得到这个回调,然后我想在主线程上执行某个任务.
我是否需要检查我是否已经在主线程上 - 或者是否因为没有执行此检查而遭受任何惩罚?请调用下面的代码?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Run Code Online (Sandbox Code Playgroud) UIButton当用户点击它时,我正在尝试以编程方式更改我创建的标题.所以,这是我创建的代码UIButton:
myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, parentView.frame.size.width, parentView.frame.size.height)];
[myButton setBackgroundColor:[UIColor blackColor]];
[myButton setAlpha:0.7];
[myButton setTitle:@"Hello" forState:UIControlStateNormal];
[myButton addTarget:self action:@selector(userClicked:) forControlEvents:UIControlEventTouchUpInside];
[parentView addSubview:myButton];
Run Code Online (Sandbox Code Playgroud)
而且,在我的userClicked:方法中,我做:
-(void) userClicked:(UIButton*)button
{
NSLog(@"USER CLICKED!!!");
if ([NSThread isMainThread])
{
NSLog(@"is main thread");
}
[button setTitle:@"Bye" forState:UIControlStateHighlighted];
[button setTitle:@"Bye" forState:UIControlStateNormal];
[button setTitle:@"Bye" forState:UIControlStateSelected];
[self someLengthyComputation];
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是我可以看到打印的日志消息:
USER CLICKED!!!
isMainThread
Run Code Online (Sandbox Code Playgroud)
但是,按钮的标题不会改变!我究竟做错了什么?
编辑:设置几个州的标题也不起作用.
EDIT2:如果我在Xcode的调试器窗口中打印按钮的描述,它会显示正确的标题!
Printing description of button->_titleView:
<UIButtonLabel: 0xa4c9310; frame = (95 216; 130 22); text = 'Bye'; clipsToBounds = YES; opaque …Run Code Online (Sandbox Code Playgroud) 我正在使用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
我正在使用dispatch_sync执行一个块,并且块正确执行.但是这个块在主线程上执行.根据Apple Doc:
串行队列(也称为专用调度队列)按照将它们添加到队列的顺序一次执行一个任务.当前正在执行的任务在由调度队列管理的不同线程(可能因任务而异)上运行.
这意味着(或我所理解的)当前正在执行的进程将在一个单独的线程上运行.
下面是我用来判断发生了什么的代码.它在NSURLConnection的didReceiveData: delegate方法中被调用(我知道我不应该在didReceiveData:delegate方法中这样做 - 但这只是一个关注dispatch_sync的示例).以下是我可以假设的不同方式作为我的结论的证明:
在全局并发队列上使用dispatch_sync
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([NSThread isMainThread]) {
NSLog(@"Main Thread");
}
else
NSLog(@"Not on Main Thread");
//Some Process
});
Run Code Online (Sandbox Code Playgroud)输出 -
Main Thread
Main Thread
Main Thread
// Main Thread printed till didReceiveData: gets called
Run Code Online (Sandbox Code Playgroud)
使用dispatch_queue_create在自己创建的队列上使用dispatch_sync
// Create queue somewhere else like this
dispatch_queue_t newQueue = dispatch_queue_create("WriteQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(newQueue, ^{
if ([NSThread isMainThread]) {
NSLog(@"Main Thread");
}
else
NSLog(@"Not on Main Thread");
//Some Process
});
Run Code Online (Sandbox Code Playgroud)输出 - …