相关疑难解决方法(0)

GCD在主线程中执行任务

我有一个可能来自任何线程的回调.当我得到这个回调,然后我想在主线程上执行某个任务.

我是否需要检查我是否已经在主线程上 - 或者是否因为没有执行此检查而遭受任何惩罚?请调用下面的代码?

dispatch_async(dispatch_get_main_queue(), ^{
   // do work here
});
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch

228
推荐指数
3
解决办法
11万
查看次数

即使我在主线程中更新它,UIButton标题文本也不会更新

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)

objective-c uibutton ios ios7 xcode5

40
推荐指数
10
解决办法
4万
查看次数

为什么这个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万
查看次数

dispatch_sync始终在主线程上调度块

我正在使用dispatch_sync执行一个块,并且块正确执行.但是这个块在主线程上执行.根据Apple Doc:

串行队列(也称为专用调度队列)按照将它们添加到队列的顺序一次执行一个任务.当前正在执行的任务在由调度队列管理的不同线程(可能因任务而异)上运行.

这意味着(或我所理解的)当前正在执行的进程将在一个单独的线程上运行.

下面是我用来判断发生了什么的代码.它在NSURLConnection的didReceiveData: delegate方法中被调用(我知道我不应该在didReceiveData:delegate方法中这样做 - 但这只是一个关注dispatch_sync的示例).以下是我可以假设的不同方式作为我的结论的证明:

  1. 全局并发队列上使用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)
  1. 使用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)

输出 - …

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

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