EXC_BAD_ACCESS(code=2,address=0xcc 異常解決 及 建議不要在子線程中刷新界面


iOS 上不建議在非主線程進行UI操作,在非主線程進行UI操作有很大幾率會導致程序崩潰,或者出現預期之外的效果。

我開始不知道這一點,在子線程中進行了彈窗操作,結果程序就出問題了!

報的錯誤是(EXC_BAD_ACCESS(code=2,address=0xcc),0x1a0ad32: movl 204(%ecx), %edx ),我以為是空指針導致的內存泄露,用了很多方法,但這問題感覺很頑固,困擾了我很多天。

后來有位大牛指點了我,問我是不是在子線程進行這個彈窗操作。。。直到此時我才明白問題出在哪里,問題順利解決。有時候出現bug卻不知道是哪引起的,這時是最糾結的,等明確了問題所在,問題就不是問題了。好了,言歸正傳。

那么在子線程中的UI操作如何處理呢?有兩種方法:

一:在子線程,你需要進行的UI操作前添加dispatch_async函數,即可將代碼塊中的工作轉回到主線程

 dispatch_async(dispatch_get_main_queue(), ^{  
            //更新UI操作  
            //.....  
        });

 dispatch_async函數是異步操作,對於比較耗時的操作也可以這樣處理: 

復制代碼
dispatch_async(dispatch_get_global_queue(0, 0), ^{  
    // 處理耗時操作的代碼塊...  
      
    //通知主線程刷新  
    dispatch_async(dispatch_get_main_queue(), ^{  
        //回調或者說是通知主線程刷新,  
    });  
      
});
復制代碼

dispatch_async開啟一個異步操作,第一個參數是指定一個gcd隊列,第二個參數是分配一個處理事物的程序塊到該隊列。

 dispatch_get_global_queue(0, 0),指用了全局隊列。

一般來說系統本身會有3個隊列。

global_queue,current_queue,以及main_queue.

獲取一個全局隊列是接受兩個參數,第一個是我分配的事物處理程序塊隊列優先級。分高低和默認,0為默認2為高,-2為低

 二:performSelectorOnMainThread

performSelectorOnMainThread是指在主線程上執行某個方法,比如數據下載后,更新UI界面等操作

  例如:在子線程中使用[self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO];

 

復制代碼
-(void)setupThread:(NSArray*)userInfor{  
  
   [NSThread detachNewThreadSelector:@selector(threadFunc:) toTarget:self withObject:(id)userInfor];  
  
}  
  
- (void)threadFunc:(id)userInfor{  
  
   NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init];  
  
   //。。。。需要做的處理。  
  
   //這里線程結束后立即返回  
  
  [self performSelectorOnMainThread:@selector(endThread) withObject:nil waitUntilDone:NO];  
  
  [pool release];  
  
}  
復制代碼

 

performSelectorOnMainThread通知主線程執行函數endThread。

再次強調子線程內不要進行任何UI操作,不要刷新界面。如果需要進行這些操作,通過dispatch_async或performSelectorOnMainThread這兩種方法,調出主線程中的方法去執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM