为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

宝慕林4294392 2019-12-02 13:55:48
我很难弄清楚如何将所有这些放在一起。我在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";    }}
查看完整描述

3 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

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]; 

    });


    });  

    });    

 }


查看完整回答
反对 回复 2019-12-02
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

基本上,要提交到后台队列的任何工作都需要遵循以下代码模式:


dispatch_queue_t queue = dispatch_queue_create("com.myappname", 0);


__weak MyClass  *weakSelf = self;  //must be weak to avoid retain cycle


//Assign async work

dispatch_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块内部进行任何更改。


查看完整回答
反对 回复 2019-12-02
  • 3 回答
  • 0 关注
  • 694 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信