将图像加载到滚动条时丢失内存警告

时间:2014-05-27 18:16:57

标签: ios objective-c memory-management uiimageview

我在UIScrollView收到内存警告,iPad上的内存总是35M。 我的滚动视图有很多UIImageViews。当我滚动时,我正在将图像加载到滚动条,其中最多3页加载图像(每页有几个图像)。
我看到当我开始滚动时,我收到警告。因为滚动时唯一发生的事情就是加载图像,这一定是问题所在。

以下是我加载图片的方法。你认为任何不好的做法,请告诉我。每个页面都会多次调用此方法。

  [self downloadImageWithURL:userUrl completionBlock:^(BOOL succeeded, NSData *tdata)
     {
         if (succeeded)
         {

             //load back
             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
                            {

                                UIImage *image=[UIImage imageWithData:tdata scale:1];
                                if (image)
                                {
                                    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.5);
                                    [image drawAtPoint:CGPointZero];

                                    image = UIGraphicsGetImageFromCurrentImageContext();
                                    UIGraphicsEndImageContext();
                                 }


                                dispatch_async(dispatch_get_main_queue(), ^
                                               {


                                                    CostumCell *thisCell= [mainCellsArray objectAtIndex:index];
                                                   UIImageView *view=thisCell.imageView;
                                                   view.clipsToBounds=YES;

                                                   [imagesAreLoading removeObject:[NSNumber numberWithLong:index]];


                                                   //LOAD 
                                                   [UIView transitionWithView:view
                                                                     duration:0.4f
                                                                      options:UIViewAnimationOptionTransitionCrossDissolve
                                                                   animations:^
                                                    {
                                                         view.image=nil;
                                                        view.image=image;

                                                    }
                                                     completion:nil];



                                               });
                             image=nil;
                            });

修改 我发现当GCD完成时,如果我注释掉将图像设置为动画中的图像视图的行,我仍然获取内存警告(图像甚至不在屏幕上)< / p>

1 个答案:

答案 0 :(得分:0)

它仍然不完全存在,但我找到了两种表现更好的方法,我很少得到警告。如果你有任何建议批准这个,我很高兴听到。 (例如,为什么我不应该像以前一样在这里加载url异步)

第一

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
 dispatch_async(queue, ^
    {
        NSDictionary *dic=[mainData objectAtIndex:index];
        NSString *userImageUrl=[dic objectForKey:@"url"];
        NSURL *userUrl=[NSURL URLWithString:userImageUrl];

        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:userUrl]];
        if (image)
        {
            UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.8);
            [image drawAtPoint:CGPointZero];

            image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        }


 dispatch_sync(dispatch_get_main_queue(), ^
        {

            view.image=image;
            [imagesAreLoading removeObject:[NSNumber numberWithLong:index]];


       });
    });

}

使用NSOperation的第二个,表现几乎相同:

[self.imageOperationQueue addOperationWithBlock:^
    {
        NSDictionary *dic=[mainData objectAtIndex:index];
        NSString *userImageUrl=[dic objectForKey:@"url"];
        NSURL *userUrl=[NSURL URLWithString:userImageUrl];

        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:userUrl]];
        if (image)
        {
            UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.8);
            [image drawAtPoint:CGPointZero];

            image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        }



        if (image != nil)
        {


            // now update UI in main queue
            [[NSOperationQueue mainQueue] addOperationWithBlock:^
            {


                view.image=image;


           }];
        }
    }];