22

这真让我抓狂!!!

每当我尝试显示具有 sourceType = UIImagePickerControllerSourceTypeCamera 的 UIImagePickerController 时,我都会收到“已收到内存警告。Level=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 设备上进行测试。

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

4

7 回答 7

17

这是很常见的。只要您处理内存警告而不会崩溃并且有足够的空间继续前进,就不要让它让您发疯。

于 2010-06-23T05:37:51.963 回答
6

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

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

- (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 中的“返回”或“保存”- > ApplicationDelegate 的方法 ,applicationDidReceiveMemoryWarning:(UIApplication *)application将被调用 -> 然后 ViewController 的方法 ,didReceiveMemoryWarning:将被调用 -> 然后 viewDidUnload -> 然后 viewDidLoad

然后你会发现一些视图已经发布并且当前视图被指向了一个意想不到的视图。

默认情况下,[super didReceiveMemoryWarning]将在调用 ViewController 的didReceiveMemoryWarning方法时运行。评论它,和viewDidUnload:viewDidLoad:方法将不会被调用。这意味着内存警告已被完全忽略。这正是我们所期望的。

于 2011-07-29T09:45:16.303 回答
5

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

其实就像你之前说的,应该没有问题。但是,这会导致它之后的视图再次加载并调用 viewDidLoad。这弄乱了我的应用程序,因为我在 viewDidLoad 中初始化了视图——现在它被重新初始化了——即使它不应该。

就像评论一样,这也可能发生在许多其他依赖于仅加载一次视图的应用程序中!

于 2010-07-18T19:34:49.753 回答
4

它确实发生在我的应用程序中,我是否也在 iOS 4.0 上做到了。这并不一致,但最常见的原因是创建一个UIImagePickerController实例并导航到存储在其中一个相册中的一些大照片。通过在方法中保持状态,并在 viewDidLoad 方法中从状态加载来
修复。didReceiveMemoryWarning一个警告是要记住在您的应用程序的正确位置清除状态持久文件。对我来说,它在正常情况下离开了相关的 UIViewController。

于 2010-07-23T17:58:47.310 回答
1

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

UIImagePickerController 对内存警告的行为似乎是自行关闭。我可以在 didReceiveMemoryWarning 方法中从父 ViewController 中关闭 UIImagePickerController,但这会导致糟糕的用户体验。

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

于 2010-09-28T19:15:03.873 回答
1

几天来,我一直在为同样的问题苦苦挣扎。但是,重置我的 iPhone 4(清除内存)解决了这个问题,所以这不是一个真正的应用程序问题。

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

我不确定这仅在使用 UIimgPickerController 时发生,因为测试所有这些非常耗时。

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

这里有一些值得深思的地方:可能是因为您正在测试您的应用程序而导致内存不足。由于存在一些内存泄漏,您很有可能在每次调试时都在努力解决这个问题。

于 2010-12-28T12:23:41.300 回答
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

于 2015-04-20T00:10:51.610 回答