【问题标题】:Memory issue while trying to save huge data in ios尝试在 ios 中保存大量数据时出现内存问题
【发布时间】:2013-12-10 00:50:31
【问题描述】:

我试图在从相机捕获多张图像后将它们保存到我的文档目录中。我要保存的大约 50 张图像。但是每次我尝试保存它们时应用程序都会崩溃,因为图像太多并且我收到内存警告。我不知道如何解决这个问题。 这是我的代码:

for (int i = 0; i<_arrImages.count; i++)
{

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
               {
NSDate *date = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
[dateFormat setDateFormat:@"dd-MMM-yyyy"];
NSString *dateString = [dateFormat stringFromDate:date];

[dateFormat setDateFormat:@"dd-MMM-yyyy HH:mm:ss"];
NSString *dateStringId = [dateFormat stringFromDate:date];


[Utils saveImage:image withName:dateStringId toFolder:kImageFolder];



UIImage *thumbImage = [image imageCroppedAndScaledToSize:CGSizeMake(150, 112) contentMode:UIViewContentModeScaleAspectFill padToFit:YES];

[Utils saveImage:thumbImage withName:dateStringId toFolder:kThumbnailFolder];


NSMutableDictionary *sendDict = [[NSMutableDictionary alloc]init];
[sendDict setObject:dateStringId forKey:kitemId];
[sendDict setObject:@"image" forKey:kitemType];
[sendDict setObject:[Utils getPathForImageName:dateStringId ofFolder:kImageFolder] forKey:kitemPath];
[sendDict setObject:kStatusUnused forKey:kitemStatus];
[sendDict setObject:dateString forKey:kitemDate];
[sendDict setObject:[Utils getPathForImageName:dateStringId ofFolder:kThumbnailFolder] forKey:kitemThumb];


[SCDatabaseHandler insertIntoMainTableValues:sendDict];
               });
}

【问题讨论】:

    标签: ios iphone database uiimage


    【解决方案1】:

    您的代码没有显示image 的来源,但您不应该同时在内存中存储所有图像。

    不要使用dispatch_async,而是使用NSOperationQueue的实例并将最大并发操作数设置为1或2。队列上的操作执行的块应该加载并保存图像,这样你就只有一个或内存中的两个图像。

    【讨论】:

    • 我还建议将循环中的代码包装在 @autoreleaspool
    • 是的,我将所有图像存储在一个数组中,这会导致进一步的问题。我应该如何使用 NSOperation 队列,因为我以前从未使用过它?我的意思是我应该如何将我的代码包装在其中?我在网上搜索了它,但教程显示了一个方法调用。我应该如何向队列中添加操作?
    • 看看NSBlockOperation类。
    • 非常感谢!通过使用操作块解决了这个问题。使用 addOperationWithBlock 添加到队列中:节省了我的时间。非常感谢!
    • @SahilTyagi 您可以使用串行调度队列,而不是在原始代码或 NSOperations 和 NSOperationQueue 中使用并发队列。 ;)
    【解决方案2】:

    有很多方法,比如创建 NSOperationQueue 或核心数据,通过像这样转换图像将图像保存为 NSData

    NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(myUIImage)];
    

    或者像这样使用自动释放池

    - (BOOL) getImageWithUrl:(NSString *)url toFile:(NSString *)toFile
        {
            @autoreleasepool
            {
                NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:url]] ;
                if (data)
                {
                    NSError *error ;
                    if ([[NSFileManager defaultManager] fileExistsAtPath:toFile])
                    {
                        NSLog(@"Existant %@", toFile) ;
                        [[NSFileManager defaultManager] removeItemAtPath:toFile error:nil] ;
                    }
                    if ([data writeToFile:toFile options:NSDataWritingAtomic error:&error]==NO)
                    {
                        NSLog(@"@Error creating file-%@ \n", toFile) ;
                        NSLog(@"@Error description-%@ \n", [error localizedDescription]) ;
                        NSLog(@"@Error suggestion-%@ \n", [error localizedRecoverySuggestion]) ;
                        NSLog(@"Error reason-%@", [error localizedFailureReason]) ;
                    }
                    else
                    {
                        return(true) ;
                    }
                }
                return(false) ;
            }
        }
    

    您可以使用 AFNetworking 管理在后台线程中下载图像并将其缓存。使用的方法取决于您的应用程序的要求。注意:代码是在没有编译或测试的情况下编写的。希望对您有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 2015-10-30
      • 1970-01-01
      相关资源
      最近更新 更多