UIImage导致整个iPhone的视图全部变黑

Posted

技术标签:

【中文标题】UIImage导致整个iPhone的视图全部变黑【英文标题】:UIImage Causing Views All Throughout the iPhone to Turn Black 【发布时间】:2011-07-13 20:38:38 【问题描述】:

好吧,这个问题很奇怪,我 99% 的肯定这不是保留/释放错误。基本上我使用 UIImagePickerController 从库或相机中获取图像,但生成的图像会导致一些......奇怪的事情发生。尽管在包含 UIImageView 的详细视图控制器中拉起图像很慢,但真正的问题是,如果我反复拉起视图控制器并关闭它,最终图像的某些部分会消失!更令人不安的是,如果我在发生这种情况后再次尝试将其拉起,则整个图像将变黑,而我的应用程序和 iPhone 本身的其他 UIView 要么剧烈闪烁,要么变黑!!!!例如,iPhone 壁纸和最初的“滑动解锁”面板分别变黑和闪烁……照片来自图书馆还是相机没有区别。如果我做这样的事情,这个问题就完全避免了(没有滞后,没有黑暗):

//UIImage* image = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage];

UIImage* image = [[UIImage alloc] initWithData:
                  [NSData dataWithContentsOfURL:
                   [NSURL URLWithString:
                    @"http://wild-facts.com/wp-content/uploads/2010/07/Diving_emperor_penguin.jpg"]]];

因此,我无法想象除了 UIImagePickerController 之外的任何问题。请注意,我仍在创建和关闭它——我只是没有从中获取图像。

起初我以为图像只是被过度释放,消失的黑色块是被覆盖的内存的一部分。但是,更改图像的保留计数没有任何区别。然后我想,也许图像太大了,当我关闭 UIImageView 时以某种方式无法正确释放!然而,从 Internet 下载几 MB 的图像不会复制该错误。然后我想,也许 UIImagePickerController 正在处理图像,而不考虑保留计数!但是复制图像也失败了。此外,这些东西怎么会影响存在于 ios 级别的视图?!我已经研究,实验和谷歌搜索,除了我之外没有人遇到过这个问题......但我并没有特别奇怪!这是苹果的问题吗?我忘记了一些明显的事情吗?我上下扫描了文档和指南都无济于事,但也许我错过了一些东西。

这些都不起作用:

增加保留计数 使用[图像复制]

这些都没有复制下载图像的问题:

减少保留计数 下载大于 1 MB 的大尺寸图片

我正在使用带有 iOS 4.2.8 的最新 Verizon iPhone(基本 SDK “覆盖”到 4.3,无论这意味着什么)。 4.2.8 可能是 Verizon 的最新版本,但 4.3 可用于使用 AT&T 的 iPhone。

这里是详细的代码。我还没有检查设备的兼容性,但这无关紧要。也许我忘记了 UIImagePickerController 的一些设置?

快速概述:我显示一个操作表,然后根据用户的输入,显示图像选择器。我使用自定义转换器将图像保存为核心数据对象(交付)上的可转换属性。我稍后将图像交给详细视图控制器以显示给用户。

IGDeliveryVC.m(无论如何,它的一部分。这是一个显示交付添加媒体的表格视图)

- (void)refresh

    [mediaDisplayArray release];

    NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"displayIndex" ascending:YES];

    mediaDisplayArray = [[NSMutableArray alloc] initWithArray:
                         [delivery.deliveryMedia sortedArrayUsingDescriptors:
                          [NSArray arrayWithObject:sortDescriptor]]];

    if (mediaDisplayArray == nil)
        mediaDisplayArray = [[NSMutableArray alloc] init];

    [self.tableView reloadData];


- (void)onAddMedia:(id)sender

#if TARGET_IPHONE_SIMULATOR

    UIImage* image = [[UIImage alloc] initWithData:
                      [NSData dataWithContentsOfURL:
                       [NSURL URLWithString:
                        @"http://wild-facts.com/wp-content/uploads/2010/07/Diving_emperor_penguin.jpg"]]];
    [delivery addImage:image];
    [self refresh];
    [image release];
    return;

#endif

    UIActionSheet *options = [[UIActionSheet alloc] initWithTitle:@"Add Media from..." 
                                                         delegate:self 
                                                cancelButtonTitle:@"Cancel"
                                           destructiveButtonTitle:nil
                                                otherButtonTitles:@"Camera", @"Library", nil];
    [options showFromToolbar:self.navigationController.toolbar];
    [options release];


- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 

    if (buttonIndex != 0 && buttonIndex != 1)
        return;

    UIImagePickerController* picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = NO;

    picker.mediaTypes = [NSArray arrayWithObjects:@"public.image",@"public.movie", nil];

    switch (buttonIndex)
    
        case 0:
            picker.sourceType = UIImagePickerControllerSourceTypeCamera;
            break;

        case 1:
            picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            break;
    

    [self presentModalViewController:picker animated:YES];


- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker
    
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    [picker release];


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

    NSString* mediaType = (NSString*)[info objectForKey:UIImagePickerControllerMediaType];

    if ([mediaType isEqualToString:@"public.image"])
    
        UIImage* image = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage];
        //UIImage* image = [[UIImage alloc] initWithData:
        //                  [NSData dataWithContentsOfURL:
        //                   [NSURL URLWithString:
        //                    @"http://wild-facts.com/wp-content/uploads/2010/07/Diving_emperor_penguin.jpg"]]];

        [delivery addImage:image];
    
    else if ([mediaType isEqualToString:@"public.movie"])
    
        NSString* videoURL = (NSString*)[info objectForKey:UIImagePickerControllerMediaURL];
        [delivery addVideo:videoURL];
    
    else
    
        NSLog(@"Error: imagePickerController returned with unexpected type %@", mediaType);
    

    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    [picker release];


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    IGMedia* media = [mediaDisplayArray objectAtIndex:indexPath.row];

    UIViewController* detailViewController = 
                [media isMemberOfClass:[IGMediaImage class]]
                ? [[IGMediaImageDetailVC alloc] initWithImage:((IGMediaImage*)media).image]
                : nil;

    if (detailViewController != nil)
        [self.navigationController pushViewController:detailViewController animated:YES];

    [detailViewController release];

IGMediaImageDetailVC.h(我使用 xib :P)

#import <UIKit/UIKit.h>


@interface IGMediaImageDetailVC : UIViewController 



@property (nonatomic, retain) UIImage* image;
@property (nonatomic, retain) IBOutlet UIImageView* imageView;

- (id)initWithImage:(UIImage*)anImage;

@end

IGMediaImageDetailVC.m

#import "IGMediaImageDetailVC.h"


@implementation IGMediaImageDetailVC

@synthesize image;
@synthesize imageView;

- (id)initWithImage:(UIImage*)anImage

    self = [super initWithNibName:@"IGMediaImageDetailVC" bundle:nil];
    if (self)
    
        self.image = anImage;
    
    return self;


- (void)dealloc

    [image release];

    [super dealloc];


- (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.


#pragma mark - View lifecycle

- (void)viewDidLoad

    [super viewDidLoad];

    self.imageView.image = self.image;


- (void)viewDidUnload

    [super viewDidUnload];

    [imageView release];


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);


@end

如果我可以做些什么来使这篇文章更清晰易读,请告诉我。我会将不起作用/复制问题的内容添加到适当的列表中。感谢您抽出宝贵时间阅读本文!

【问题讨论】:

【参考方案1】:

我刚刚发现了问题,与过度使用内存有关。感谢这篇令人惊叹的帖子:https://***.com/questions/1282830/uiimagepickercontroller-uiimage-memory-and-more 基本上,在显示图像之前,我将每个维度除以 4,结果总共是我之前使用的内存的 1/16。这是我使用的方法(根据很棒的帖子):

+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize;

    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;

在方法调用中,我传入CGSizeMake(image.size.width/4, image.size.height/4)

希望这对您有所帮助!

【讨论】:

以上是关于UIImage导致整个iPhone的视图全部变黑的主要内容,如果未能解决你的问题,请参考以下文章

iOS动画连续背景?

flutter开发使用AnnotatedRegion修改状态栏字体颜色,导致导航栏也变黑了的解决方法

背景颜色(colorWithPatternImage)没有填充 iPad 的整个视图

iPhone:UIImage 背景颜色与 UIView 背景颜色不同

setNeedsDisplayInRect:导致整个视图被更新

左侧单点触控 iphone 上带有圆角的 UIImage