为什么在iPhone上以17秒+的速度将这些图像保存到核心数据?

时间:2010-06-23 13:23:47

标签: iphone core-data uiimage

我一直在使用Apple的iPhone CoreDateRecipes示例代码来了解有关tableviews和核心数据的更多信息。我根据该样本编写了自己的测试应用程序,除了一件事情外,它运行良好。当我为“配方”选择照片时,无论是来自相机还是库,当我点击“完成”离开编辑模式时,在将控制权交还给用户之前大约需要15秒。在设备上进行测试时会发生这种情况 - 在模拟器中,仍有延迟,但只有2-4秒。

我在没有选择照片和编辑其他数据的情况下测试了“编辑/完成”按钮,并且它立即保存,所以我很确定图像应该受到责备。下面是它离开编辑模式的代码,以及图像处理代码 - 我可以添加/更改/删除什么来加快速度?我知道这些示例代码片段只是概念的证明,但我无法相信他们发布了一个具有如此糟糕的用户体验的示例!

一如既往地感谢任何指导......如果您还需要查看其他任何代码,请告知我们,或you can see the whole sample project here

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self updatePhotoButton];

    nameTextField.enabled = editing;
    overviewTextField.enabled = editing;

    [self.navigationItem setHidesBackButton:editing animated:YES];


    if (!editing) {
        NSManagedObjectContext *context = recipe.managedObjectContext;
        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"Error in RecipeDetailViewController:setEditing -- %@, %@",error, [error userInfo]);
            abort();
        }
    }
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)selectedImage editingInfo:(NSDictionary *)editingInfo {

    NSManagedObject *oldImage = recipe.image;
    if (oldImage != nil) {
        [recipe.managedObjectContext deleteObject:oldImage];
    }

    NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:recipe.managedObjectContext];
    recipe.image = image;

    [image setValue:selectedImage forKey:@"image"];
    CGSize size = selectedImage.size;
    CGFloat ratio = 0;
    if (size.width > size.height) {
        ratio = 70.0 / size.width;
    } else {
        ratio = 70.0 / size.height;
    }

    CGRect rect = CGRectMake(0.0, 0.0, ratio * size.width, ratio * size.height);

    UIGraphicsBeginImageContext(rect.size);
    [selectedImage drawInRect:rect];
    recipe.thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [self dismissModalViewControllerAnimated:YES];
}

3 个答案:

答案 0 :(得分:3)

首先,正如吉尔伯特指出的那样,示例代码不适合生产使用,而且速度很慢。

其次,您不应将图像存储在Core Data中。该示例可能会显示如何执行此操作但通常是非常糟糕的主意。您应该将图像存储在磁盘上,然后将指针(文件路径)保留在Core Data中的图像中。这条规则有一些例外(非常小的图像),但你应该重新考虑你的设计。

最后,您看到的许多缓慢可能与核心数据无关。图像选择器代码本身非常慢。我建议将代码更改为只写入磁盘,看看与写入Core Data相比有多慢。如果它快得多,我会感到惊讶。

更新

您可以在Core Data中存储小图像,并从其他帖子中获得我的建议,比iOS更多的桌面。原因是缓存。在iOS上,Core Data使用的缓存非常小。如果将图像存储在大型数据库中,则可以轻松地清除该缓存,并导致应该在缓存中的未来调用将命中磁盘。这不是“不存储二进制数据”的硬性规则,而是更多关注性能规则的规则,如果您的磁盘数量超出预期,二进制数据可能很容易成为原因。

联系人

关于联系人,你可能会变慢,因为他们的工作方式与你不同,他们很容易使用私有API来访问相机。因为它是Apple,它们不一定遵循与我们相同的规则。

答案 1 :(得分:0)

我不是iPhone开发人员,但一般来说,示例代码没有考虑用户体验。示例代码显示了示例。

通常,您需要在其他线程中执行昂贵的(长时间运行)操作。

也许这篇博文会有所帮助:Respect the Main Thread

答案 2 :(得分:0)

我下载了项目,构建并在模拟器中运行它。我无法重现你的问题。我发现保存图像所花费的时间在视觉上是瞬时的,即不长于视图转换。

如果您在原始未经修改的项目中看到同样的问题,那么您还有其他事情要做。确保您拥有项目的最新版本,该版本应该是您链接的版本。我知道至少有一个非常旧的,因为我最近打了它。