收到内存警告。显示UIImagePickerController时Level = 1

时间:2010-06-23 05:02:57

标签: iphone objective-c uiimagepickercontroller didreceivememorywarning

这让我发疯了!!!

每当我尝试使用sourceType = UIImagePickerControllerSourceTypeCamera显示UIImagePickerController时,我都会收到“已接收内存警告。级别= 1”。

以下是我设置的viewDidLoad中的代码:

    - (void)viewDidLoad {

    [super viewDidLoad];

    // Set card table green felt background
    self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"green_felt_bg.jpg"]];


    // Init UIImagePickerController
    // Instantiate a UIImagePickerController for use throughout app and set delegate
    self.playerImagePicker = [[UIImagePickerController alloc] init];
    self.playerImagePicker.delegate = self;
    self.playerImagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}

以下是我以模态方式呈现的方式..

- (IBAction) addPlayers: (id)sender{
[self presentModalViewController:self.playerImagePicker animated:YES];

}

结果...... UIImagePicker开始显示然后繁荣......我得到了记忆警告......每一次!有趣的是,如果我切换到sourceType = UIImagePickerControllerSourceTypePhotoLibrary ......一切正常。

我错过了什么或做错了什么?我想做的就是显示相机,拍摄并保存图片。

仅供参考 - 我正在测试我的3GS设备。

感谢任何可以提供帮助的人:)

7 个答案:

答案 0 :(得分:17)

这是very common。只要您处理内存警告而不会崩溃并且有足够的空间继续运行,请不要让它让您发疯。

答案 1 :(得分:6)

这不是关于您的应用程序使用了多少内存,因为即使您编写一个非常简单的应用程序,只有一个视图只有一个按钮,单击按钮然后打开相机,它可能会发生。 我已经在iPhone 3GS,iPad 2和iPod touch 3G上进行了测试。它只发生在iPhone 3GS上。 我发现如果你在执行应用程序之前重新启动设备,它就不会再发生了。

另一个真正的解决方案是在viewController中对代码[super didReceiveMemoryWarning]进行注释。

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

经过iOS 4.3.2对iPhone 3GS的大量测试后,我发现逻辑可能是这样的: - >打开与在后台运行的应用程序一样多 - >呈现UIImagePickerController的imagePicker,单击imagePicker中的“Back”或“Save” - >将调用ApplicationDelegate的方法applicationDidReceiveMemoryWarning:(UIApplication *)application - >然后将调用ViewController的方法didReceiveMemoryWarning: - >然后是viewDidUnload - >然后是viewDidLoad

然后你可以找到一些已发布的视图,并且当前视图已指向意外的视图。

默认情况下,[super didReceiveMemoryWarning]将在调用ViewController的didReceiveMemoryWarning方法时运行。对其进行评论,并且不会调用viewDidUnload:viewDidLoad:方法。这意味着mem警告已被完全忽略。这就是我们的预期。

答案 2 :(得分:5)

现在我升级到4.0后,它也发生在我的应用程序中 - 在3.1之前没有警告。

实际上正如你之前所说,应该没有问题。但是,这会导致再次加载后调用视图并调用viewDidLoad。这会弄乱我的应用程序,因为我在viewDidLoad中初始化视图 - 现在它再次被初始化 - 即使它不应该。

正如评论一样,许多其他依赖加载视图的应用也可能会发生这种情况!

答案 3 :(得分:4)

答案 4 :(得分:1)

我也在打开UIImagePickerController时收到内存警告。我也是4.01。 但另外,UIImagePickerController正在运行关闭快门动画并在那里停止,屏幕上关闭快门。

看起来UIImagePickerController对内存警告的行为就是关闭它自己。 我可以从didReceiveMemoryWarning方法中的父ViewController中解除UIImagePickerController,但这会导致糟糕的用户体验。

有没有人见过这个问题? 有没有办法处理内存警告,以便UIImagePickerController不会自行关闭?

答案 5 :(得分:1)

我几天来一直在努力解决同样的问题。但是,重置我的iPhone 4(清除内存)可以解决问题,因此这不是一个应用程序问题。

似乎1级或2级内存警告触发UIimgPickerController委托卸载自身。在我的应用程序中,代理人的委托也是如此(是的,它可以)。然而,在内存警告之后,它将再次加载委托(及其委托),导致viewDidLoad执行其中的任何代码。

我不确定只有在使用UIimgPickerController时才会发生这种情况,因为测试所有这些都非常耗时。

我可以编写一些额外的代码来防止viewDidLoad中的代码使viewWillAppear在显示UIimgPickerController时执行,但这不是优雅的,对吗?

  

这是值得深思的东西:它可能是   你的内存不足   因为您正在测试您的应用同   一些记忆很好   可能你正在努力   每次调试都会出现此问题。

答案 6 :(得分:1)

UIImagePickerControllerDelegate是一种内存耗尽,因为您正在捕获高内存资产,无论是图像还是视频。所以从一开始就一定要指定中等捕获设置,作为一个起点,如果你不需要质量,请减少它:

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.videoQuality=UIImagePickerControllerQualityTypeMedium;

然后捕获并使用这些资产。从应用程序临时文件夹中删除所有临时文件。可能是一个额外的强迫性步骤,但它是一个好习惯:

NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:[lastCapturedFile substringFromIndex:7] ]) {
    NSError *error;
    // Attempt to delete the folder containing globalDel.videoPath
    if ([fileManager removeItemAtPath:[lastCapturedFile substringFromIndex:7] error:&error] != YES) {
        NSLog(@"Unable to delete recorded file: %@", [error localizedDescription]);
    } else {
        NSLog(@"deleted file");
    }
}

上面是清除委托创建的文件。在某些情况下,如果您要转码或创建自己的资源,请删除包含该文件的文件夹。请注意,我正在删除url字符串的'file://'部分,因为文件管理器不喜欢它:

[lastCapturedFile substringFromIndex:7]

您需要考虑的其他事项包括您使用该资产所做的工作 - 转码,缩小图像等等。请注意,如果AVFoundation正在显示,使用UIImagePickerViewController的任何转码都将崩溃。