2012-03-02 124 views
0

我正在開發一個應用程序,其中我的桌面視圖中顯示了很多圖像。這些圖像必須來自服務器,因此我創建了另一個線程,在該線程中圖像得到處理然後在表格視圖單元格上進行設置,以使我們的表格視圖順利且正確地滾動。 我的問題是,當我滾動我的表視圖的次數,應用程序獲得凍結,一段時間後,Xcode的顯示下圖所示的消息: - enter image description here多個NSThreads同時運行導致應用程序凍結

My table view cell code :- 

    id object = [imageDictFunctionApp objectForKey:[NSString stringWithFormat:@"%d",functionAppButton.tag]]; 
        if(!object){  

         NSArray *catdictObject=[NSArray arrayWithObjects:[NSNumber numberWithInt:functionAppButton.tag],indexPath,[NSNumber numberWithInt:i],nil]; 
         NSArray *catdictKey=[NSArray arrayWithObjects:@"btn",@"indexPath",@"no",nil]; 
         NSDictionary *catPassdict=[NSDictionary dictionaryWithObjects:catdictObject forKeys:catdictKey]; 
         [NSThread detachNewThreadSelector:@selector(displayingSmallImageForFunctionsApps:) toTarget:self withObject:catPassdict]; 

        } 
        else 
        { 
         if(![object isKindOfClass:[NSNull class]]){ 
          UIImage *img = (UIImage *)object; 
          [functionAppButton setImage:img forState:UIControlStateNormal]; 
         } 


-(void)displayingSmallImageForFunctionsApps:(NSDictionary *)dict 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSIndexPath *path=[dict objectForKey:@"indexPath"]; 
    NSArray *catArray=[self.functionDataDictionary objectForKey:[self.functionsKeysArray objectAtIndex:path.row]]; 
    int vlaue=[[dict objectForKey:@"no"] intValue]; 
    NSDictionary *dict1=[catArray objectAtIndex:vlaue]; 
    NSString *urlString=[dict1 objectForKey:@"artwork_url_large"]; 
    NSURL *url = [NSURL URLWithString:urlString]; 
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; 

    if(image){ 
     [imageDictFunctionApp setObject:image forKey:[NSString stringWithFormat:@"%d",[[dict objectForKey:@"btn"] intValue]]]; 
     NSMutableDictionary *dict2=[NSMutableDictionary dictionaryWithCapacity:4]; 
     [dict2 setObject:image forKey:@"imageValue"]; 
     [dict2 setObject:[dict objectForKey:@"btn"] forKey:@"tag"]; 
     [dict2 setObject:[dict objectForKey:@"indexPath"] forKey:@"indexPath"]; 
     [self performSelectorOnMainThread:@selector(setImageInCellDictCategroryTable:) withObject:dict2 waitUntilDone:NO]; 


    } 
    else{ 
     [imageDictFunctionApp setObject:[NSNull null] forKey:[NSString stringWithFormat:@"%d",[[dict objectForKey:@"btn"] intValue]]]; 
    } 

    [pool drain]; 

} 

- (void)setImageInCellDictCategroryTable:(NSDictionary *)dict{ 
    UITableViewCell *myCell = (UITableViewCell *)[categoriesAndFunctionsTableView cellForRowAtIndexPath:[dict objectForKey:@"indexPath"]]; 
    UIButton *myBtn = (CustomUIButton *)[myCell viewWithTag:[[dict objectForKey:@"tag"] intValue]]; 
    if ([dict objectForKey:@"imageValue"]) { 
     [myBtn setImage:[dict objectForKey:@"imageValue"] forState:UIControlStateNormal]; 
    } 
} 

我已經張貼了我的所有代碼這可能與此錯誤有關。請任何人建議我如何解決此問題。

在此先感謝!

回答

1

所以我猜想發生的是你是running out of Mach ports。它看起來像你正在爲表中的每個單元格啓動一個線程,然後他們都試圖安排任務在主runloop上運行時完成。這會給你的系統帶來壓力。

我會爲每個圖像創建一個NSOperation,並將它們安排在同一個NSOperationQueue中。運行時將使用調整到特定系統的線程池來運行所有操作。

對於這樣一個簡單的事情,你也可以像奧斯卡所說的那樣使用GCD,但是我最近在Apple列表上看到NSOperationQueue是首選,因爲它的級別更高。它爲您提供更多選項來控制後臺任務發生的情況。

+0

非常感謝你的答案。我嘗試過使用NSOperationQueue,現在應用程序不是沒有凍結,但沒有圖像在我的按鈕上。對象:catPassdict];我們可以通過下面的例子來說明如何使用NSInvocationOperation。 \t \t \t \t \t \t \t \t \t \t \t \t [functionOperationQueue addOperation:invOperation]; \t \t \t \t \t \t \t [invOperation release]; functionOperationQueue是我的全局變量。請你看看我做錯了什麼。 – Gypsa 2012-03-05 05:44:00

+0

@Gypsa:當你得到圖像時,你可能需要強制表格視圖重新顯示。 – JeremyP 2012-03-05 10:36:47

+0

一旦表格滾動,我看到現在顯示的SmallImageForFunctionsApps沒有被調用。它是當滾動或滾動操作後沒有添加到隊列中。 – Gypsa 2012-03-06 04:04:39

2

我會建議不要使用線程,並將您的代碼移動到GCD,看起來像你想使用的是一個串行隊列。

+0

最近在Apple列表中,有人說您應該使用可用的最高級API。在這種情況下,這將是'NSOperationQueue'。 – JeremyP 2012-03-02 13:59:10

+0

我個人比較喜歡GCD到NSOperationQueue。 – Wevah 2012-03-02 14:02:52

+0

@ Wevah:我不是說GCD已被棄用或者其他任何東西,這正是我在Apple列表上讀到的。就我個人而言,我更喜歡NSOperationQueue,因爲它是Objective-C,但在這種情況下,所有後臺處理都在一個函數中,將一個塊粘在GCD隊列上並不成問題。 – JeremyP 2012-03-02 14:14:28