1

您好,我正在开发一个应用程序,该应用程序从网络加载图像以填充内容视图。我正在使用“MGBox2”将视图加载到部分中,并且我在 mgbox2 示例中使用了“Photobox”类的修改版本。

我的问题是,当我从网络加载图像时,即使我从超级视图中解除/删除视图控制器和包含它们的视图,图像视图对象也会保留在内存中。

当我查看内存分配时,我发现我有大量的“malloc 9.00kb”对象,保留计数为 1,指向

UIImage* image = [UIImage imageWithData:weakData];

线。这是我加载图像并将其放入照片箱的整个代码:

我的代码看起来一团糟,因为我一直在尝试新事物,而且我知道我在理解 arc 的工作原理方面遇到了一些问题。尝试将数据设置为 __weak 但如您所见,仍然没有运气..

另请注意,如果图像 url 中包含“发布者”字样,我会将其保存到文档目录以缓存在磁盘上。

- (void)loadPhotoFromURL:(NSString*)photoUrl; {

    bool hasLoaded = NO;
    for(id view in self.subviews){
        if([[view class] isSubclassOfClass:[UIImageView class]])
            hasLoaded = YES;
    }
    if(!hasLoaded){
        id fullPath = photoUrl;
        bool willCachePhoto = NO;
        if([photoUrl rangeOfString:@"publishers"].location!=NSNotFound){
            willCachePhoto = YES;
        }
        NSData* data;
        ASIHTTPRequest* request;
        if(willCachePhoto)
            data = [NewsUtil loadData:[fullPath md5]];
        if(!data){
            NSURL *url = [NSURL URLWithString:fullPath];
            request = [[ASIHTTPRequest alloc]initWithURL:url];
            [request startSynchronous];
            data = [request responseData];
            if(willCachePhoto){
                [NewsUtil saveData:data withName:[fullPath md5]];
            }
        }[request clearDelegatesAndCancel];
        // do UI stuff back in UI land
        dispatch_async(dispatch_get_main_queue(), ^{
            @autoreleasepool {
                // ditch the spinner
                UIActivityIndicatorView *spinner = self.subviews.lastObject;
                [spinner stopAnimating];
                [spinner removeFromSuperview];

                // failed to get the photo?
                if (!data) {
                    self.alpha = 0.3;
                    return;
                }
                __unsafe_unretained NSData* weakData = data;
                UIImage* image = [UIImage imageWithData:weakData];
                UIImageView* imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
                imageView.image = image;
                [self insertSubview:imageView atIndex:0];
                imageView.size = self.size;
                imageView.alpha = 0;
                imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth
                | UIViewAutoresizingFlexibleHeight;

                // fade the image in
                [UIView animateWithDuration:0.2 animations:^{
                    imageView.alpha = 1;
                }];
                for(id v in self.subviews){
                    if([[v class]isSubclassOfClass:[UILabel class]]){
                        UILabel* lbl = (UILabel*)v;
                        NSLog(@"lbl title: %@",lbl.text);
                        [self bringSubviewToFront:lbl];
                        break;
                    }
                }
            }//autorelease pool
        });
    }
}

感谢您的帮助!

4

2 回答 2

1

好像我已经解决了将 imageWithData 更改为 imageWithContentsOfFile 构造函数的问题。这是我的新照片箱电话:

首先,我将图像放入 temproraycache(在少数情况下也放入永久缓存),然后我从缓存存储中调用带有文件名的图像...

        [wRequest setCompletionBlock:^{
            @autoreleasepool {
//                UIImage* image = [[UIImage alloc] initWithContentsOfFile:[[ASIDownloadCache sharedCache] pathToCachedResponseDataForURL:[NSURL URLWithString:photoUrl]]];;
                UIImage* image = [UIImage imageWithContentsOfFile:[[ASIDownloadCache sharedCache] pathToCachedResponseDataForURL:[NSURL URLWithString:photoUrl]]];
                dispatch_async(dispatch_get_main_queue(), ^{

                    UIActivityIndicatorView *spinner = self.subviews.lastObject;
                    [spinner stopAnimating];
                    [spinner removeFromSuperview];
                    if (!image) {
                        self.alpha = 0.3;
                        return;
                    }
                    UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
                    imageView.size = self.size;
                    imageView.alpha = 0;
                    imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth
                    | UIViewAutoresizingFlexibleHeight;
                    __weak UIImageView* wimageView = imageView;
                    [self insertSubview:wimageView atIndex:0];
                    [UIView animateWithDuration:0.3f animations:^{
                        wimageView.alpha = 1;
                    }];
                    imageView = nil;
                });
                image = nil;
            }
        }];
于 2013-06-18T15:07:48.437 回答
0

您保留 UIImageView 实例两次。首先是使用 alloc 创建它,然后将它插入另一个视图 (insertSubview)。该父视图将保留它。

插入:[imageView 发布];

行后:[self insertSubview:imageView atIndex:0];

已编辑:如果您使用的是 ARC,那么我的回答无效。请忽略它。

于 2013-06-06T12:50:55.970 回答