GCD,线程,程序流和UI更新

我很难弄清楚如何将所有这些放在一起。我在Mac上有一个难题解决应用程序。您输入难题,按一个按钮,然后它尝试查找解决方案的数量,最小移动量等,因此我想保持UI更新。然后,一旦计算完成,请重新启用按钮并更改标题。


以下是按钮选择器和解决功能的一些示例代码:(请记住,我从Xcode复制/粘贴,因此可能缺少一些{}或其他拼写错误..但是它应该可以使您了解我的想法。我正在尝试做。


基本上,用户按下一个按钮,该按钮为ENABLED = NO,调用此函数来计算拼图。在计算时,请使用移动/解决方案数据更新UI标签。然后,一旦完成拼图计算,Button为ENABLED = YES;


按下按钮时调用:


- (void) solvePuzzle:(id)sender{

    solveButton.enabled = NO;

    solveButton.title = @"Working . . . .";


    // I've tried using this as a Background thread, but I can't get the code to waitTilDone before continuing and changing the button state.

    [self performSelectorInBackground:@selector(createTreeFromNode:) withObject:rootNode];


    // I've tried to use GCD but similar issue and can't get UI updated.

    //dispatch_queue_t queue = dispatch_queue_create("com.gamesbychris.createTree", 0);

    //dispatch_sync(queue, ^{[self createTreeFromNode:rootNode];});


    }


    // Need to wait here until createTreeFromNode is finished.

    solveButton.enabled=YES;

    if (numSolutions == 0) {

    solveButton.title = @"Not Solvable";

    } else {

        solveButton.title = @"Solve Puzzle";

    }

}


宝慕林4294392
浏览 695回答 3
3回答

沧海一幻觉

dispatch_queue_t backgroundQueue;  backgroundQueue = dispatch_queue_create("com.images.bgqueue", NULL);            - (void)process {        dispatch_async(backgroundQueue, ^(void){    //background task        [self processHtml];    dispatch_async(main, ^{ // UI updates in main queue   [self workDone];     });    });      });     }

饮歌长啸

基本上,要提交到后台队列的任何工作都需要遵循以下代码模式:dispatch_queue_t queue = dispatch_queue_create("com.myappname", 0);__weak MyClass  *weakSelf = self;  //must be weak to avoid retain cycle//Assign async workdispatch_async(queue, ^{    [weakSelf doWork];    dispatch_async(dispatch_get_main_queue(),    ^{       [weakSelf workDone];     }); });  queue = nil;  //Using ARC, we nil out. Block always retains the queue.永不忘记:上面的1-queue变量是一个引用计数对象,因为它是一个专用队列,而不是全局队列。因此,它被在该队列内执行的块保留。在此任务完成之前,不会释放它。2-每个队列都有自己的堆栈,这将作为递归操作的一部分进行分配/释放。您只需要担心引用成员计数的类成员变量(强,保留等),这些变量可以在上面的doWork中访问。3-在后台队列操作中访问那些引用计数的var时,您需要根据应用程序的使用情况使它们成为线程安全的。示例包括对对象(例如字符串,数组等)的写操作。这些写操作应封装在@synchronized关键字中,以确保线程安全访问。@synchronized 确保在执行其封装的块期间,没有其他线程可以访问其保护的资源。@synchronized(myMutableArray){    //operation}在上面的代码块中,任何其他线程都不允许myMutableArray对该@synchronized块内部进行任何更改。
打开App,查看更多内容
随时随地看视频慕课网APP