0

我的应用程序由于在应用程序使用过程中的某个时间点出现内存压力而终止,我已将问题隔离为导致问题的一大块代码。

我将复制下面的代码(我通过注释掉这段代码并运行应用程序进行了测试,应用程序运行良好)。

我在这里要做的是:我正在阅读 RSS 提要,获取图像的 URL 并将其显示在 tableView 单元格中。下面的代码来自 cellForRowAtIndexPath。

// 1. Check the image cache to see if the image already exists. If so, then use it. If not, then download it.
    if ([[ImageCache sharedImageCache] DoesExist:imgSrcString] == true)
    {
        cell.cellImageView.image = [[ImageCache sharedImageCache] GetImage:imgSrcString];
    } else {
        cell.cellImageView.image = [UIImage imageNamed:@"NoImage_Small"];
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
        // Now, we can’t cancel a block once it begins, so we’ll use associated objects and compare
        // index paths to see if we should continue once we have a resized image.
        objc_setAssociatedObject(cell,
                                 kIndexPathAssociationKey,
                                 indexPath,
                                 OBJC_ASSOCIATION_RETAIN);

        dispatch_async(queue, ^{
            NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgSrcString]];
            UIImage *image = [UIImage imageWithData:imageData];
            //UIImage *resizedImage = [image scaleToSize:CGSizeMake(71.0f,71.0f)] ; //[UIImage resizeImage];
            dispatch_async(dispatch_get_main_queue(), ^{
                NSIndexPath *cellIndexPath =
                (NSIndexPath *)objc_getAssociatedObject(cell, kIndexPathAssociationKey);
                if(image){
                    if ([indexPath isEqual:cellIndexPath]) {
                        [[cell cellImageView] setImage:image];
                        [[ImageCache sharedImageCache] AddImage:imgSrcString :image];
                    }
                }

                // [[ImageCache sharedImageCache] AddImage:[imgSrcString stringByAppendingString:@"bigImage"] :image];
            });
        });
    }

任何帮助我指出正确方向的帮助将不胜感激。谢谢你的时间 !

4

2 回答 2

1

关于这个问题我已经冲浪了。顺便说一句,在他们提到的一些博客中,默认情况下 NSURLConnection 包含根本不清晰的缓存。这可能是坠机的原因。所以尝试使用 ASIHTTPRequest http://allseeing-i.com/ASIHTTPRequest/然后你就不会感觉到关于图像下载的内存警告。

使用此代码进行 ASIHTTPRequest 集成(添加 sdk 文件后)

-(void)resetNetworkQueue
{
    // initialising network queue.
    self.networkQueue =[[ASINetworkQueue alloc]init];

    [self.networkQueue setRequestDidFinishSelector:@selector(mediaDownloadCompleted:)];
    [self.networkQueue setRequestDidFailSelector:@selector(mediaDownloadFailed:)];
    [self.networkQueue setRequestDidStartSelector:@selector(mediaDownloadStarted:)];
    [self.networkQueue setQueueDidFinishSelector:@selector(networkQueueCompletedProcess:)];
    [self.networkQueue setMaxConcurrentOperationCount:10];
    [self.networkQueue setShouldCancelAllRequestsOnFailure:NO];

    [self.networkQueue setDelegate:self];

}


-(void)createDownloadRequest
{
  //Adding request in network queue.
  self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:imageURL]];
    [self.request setDownloadDestinationPath:downloadDestinationPath];
    [self.request setDelegate:self];
    [self.request setAllowResumeForFileDownloads:YES];
    [self.request setTimeOutSeconds:30];
    [self.networkQueue addOperation:self.request];
    [self.request setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:homeInfo,@"FloorPlanInfo",imageType,@"ImageType", nil]];
}



- (void)mediaDownloadStarted:(ASIHTTPRequest *)request
{
   //Fire when request started. 
}
- (void)mediaDownloadCompleted:(ASIHTTPRequest *)request
{

     //Fire when request completed. 
}
- (void)mediaDownloadFailed:(ASIHTTPRequest *)request
{
    //Fire when request Failed to download. 
}
于 2013-11-13T06:15:34.453 回答
0

我认为主要问题不是代码中的多线程,而是我正在下载大图像并将它们存储在 ImageCache 中,这很快变得臃肿并导致崩溃。我解决这个问题的方法是在下载后调整图像大小,然后在缓存中添加较小的图像(无论如何我都将它用作缩略图,所以不需要存储大图像)。这大大减少了崩溃的次数。希望它可以帮助处于类似情况的人。

于 2013-11-14T05:41:22.707 回答