多个NSThread同时运行导致应用程序冻结

时间:2012-03-02 13:28:54

标签: iphone objective-c tableview nsurl nsthread

我正在开发一个应用程序,其中我在我的表视图中显示了很多图像。这些图像必须来自服务器,所以我创建了另一个线程,其中图像被处理,然后在表视图单元格上设置使我们的表格视图平滑而正确地滚动。 我的问题是,当我将表格视图滚动多次时,应用程序会冻结,一段时间后xcode会显示下图所示的消息: - enter image description here

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

我发布了可能与此错误相关联的所有代码。有人建议我如何解决此问题。

提前致谢!

2 个答案:

答案 0 :(得分:2)

我建议不要使用线程并将代码移到GCD,看起来你想要使用的是一个串行队列。

答案 1 :(得分:1)

所以我猜想发生的事情是你running out of Mach ports。在我看来,你正在为表中的每个单元格启动一个线程,然后他们都在尝试安排任务在完成后在主runloop上运行。这会给你的系统带来压力。

我会为每张图片创建一个NSOperation,并在同一个NSOperationQueue上安排它们。运行时将使用调整到特定系统的线程池来运行所有操作。

对于这样一个简单的事情,你也可以像奥斯卡所说的那样使用GCD,但我最近在Apple列表中读到NSOperationQueue是首选,因为它更高级别。它为您提供了更多选项来控制后台任务的发生。