在dispatch_async中收到内存警告

时间:2015-11-30 05:17:25

标签: ios uitableview uiimageview grand-central-dispatch

这是我在 <div id="x"> </div> <script> $(document).ready(function(){ $("#x").load("/controller/action"); }); </script> 中编写的用于下载图像的代码:

{{1}}

但是如果有超过6张图像,我在控制台上收到以下消息的内存异常:

  

来自调试器的消息:由于内存问题而终止

2 个答案:

答案 0 :(得分:4)

下载逻辑没有任何问题。问题是您正在尝试将图像保存在阵列中,最终会增加应用程序内存。由于您持有的图像是压缩的png,它们看起来不会占用太多大小,但它会大大增加应用程序的内存并导致应用程序崩溃。

要解决您的问题,您需要在下载后立即将每个文件保存到文档目录,然后保存图像的名称(或缩略图,如果您需要在某处显示),而不是整个分辨率图片。

<强>更新

您可以使用Xcode中的工具工具分析应用程序的内存分配。它可以为您提供消耗最多内存的对象的提示。

答案 1 :(得分:1)

正如@Marek R所说,你必须使用简单逻辑的块。首先,创建一个只从url下载图像异步的方法。

var cache = NSCache()

func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
    var data: NSData? = self.cache.objectForKey(urlString) as? NSData

    if let goodData = data {
        let image = UIImage(data: goodData)
        dispatch_async(dispatch_get_main_queue(), {() in
            completionHandler(image: image, url: urlString)
        })
        return
    }

    var downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
        if (error != nil) {
            completionHandler(image: nil, url: urlString)
            return
        }

        if data != nil {
            let image = UIImage(data: data)
            self.cache.setObject(data, forKey: urlString)
            dispatch_async(dispatch_get_main_queue(), {() in
                completionHandler(image: image, url: urlString)
            })
            return
        }

    })
    downloadTask.resume()
})

}

其次,调用imageFromUrl方法,然后从块中继续进行图像修改:

imageForUrl("http://useYourLinkHere/image.png", completionHandler:{(image: UIImage?, url: String) in
    self.imgUser.image = image!
})

        imgUser.contentMode = UIViewContentModeScaleAspectFill;
        CGSize size;
        if(imgUser.image.size.width > imageFrame.size.width || imgUser.image.size.height > rectImage.size.height)
        {
            if(imgUser.image.size.width < imageFrame.size.width)
            {
                rectImage.size.width = imgUser.image.size.width;
            }

            if(imgUser.image.size.height < rectImage.size.height)
            {
                rectImage.size.height = imgUser.image.size.height;
            }

            size = CGSizeAspectFit(imgUser.image.size, rectImage.size);
            imgUser.frame = CGRectMake(imgUser.frame.origin.x, rectImage.origin.y, size.width, size.height);

            height = imgUser.frame.size.height;
        }
        else
        {
            imgUser.frame = CGRectMake(imageFrame.origin.x, imageFrame.origin.y, imgUser.image.size.width, imgUser.image.size.height);
            height = imgUser.image.size.height;

        }

        CGPoint contentOffset = tableMessageDetail.contentOffset;
        [tableMessageDetail beginUpdates];
        [tableMessageDetail endUpdates];
        [tableMessageDetail setContentOffset:contentOffset];

        messageDocument.Pic = data;
        data = nil;
    if(messageDocument.Pic != nil)
    {
        Attachment *attachment = [Attachment new];
        attachment.DocId = messageDocument.DocId;
        attachment.DocURL = messageDocument.DocURL;
        attachment.ImageId = messageDocument.ImageId;
        attachment.MessageId = messageDocument.MessageId;
        attachment.SmallImageURL = messageDocument.SmallImageURL;
        attachment.OriginalFileName = messageDocument.OriginalFileName;
        if([messageDocument.DocURL isEqual:@""])
        {
            NSArray *attachmentArray = [messageDocument.SmallImageURL componentsSeparatedByString:@"/"];
            NSString *attachmentName = [attachmentArray objectAtIndex:attachmentArray.count - 1];
            attachment.AttachmentName = attachmentName;
        }
        else
        {
            NSArray *attachmentArray = [messageDocument.DocURL componentsSeparatedByString:@"/"];
            NSString *attachmentName = [attachmentArray objectAtIndex:attachmentArray.count - 1];
            attachment.AttachmentName = attachmentName;
        }

        attachment.Pic = messageDocument.Pic;
        [[CommonModel shared]CreateAttachment:attachment];
        [[CommonModel shared]UpdateMessageDocumentPic:messageDocument];

        attachment = nil;
    }

您在块中使用的代码应该在许多方法中断,其中一个应该被调用:&#39; resizeImageFrame()&#39;另一个应该是&#39; loadModel()&#39;,以获得有序代码。

祝你好运!