UIImage вызывает взгляды на всем протяжении iPhone, чтобы стать черным - PullRequest
1 голос
/ 14 июля 2011

Хорошо, эта проблема довольно странная, и я на 99% уверен, что это не ошибка сохранения / выпуска. В основном я использую UIImagePickerController для захвата изображения из библиотеки или с камеры, но получающееся изображение вызывает некоторые ... странные вещи. Хотя тянуть изображение вверх в контроллере подробного представления, содержащем UIImageView, затруднительно, реальная проблема заключается в том, что, если я периодически поднимаю контроллер вида и отклоняю его, в конечном итоге части изображения исчезнут !!! Что еще более тревожно, если я попытаюсь снова подтянуть его после того, как это произойдет, все изображение станет черным, а другие UIViews во всем приложении и на iPhone будут либо дико мерцать, либо почернеть !!!! Например, и обои 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! Однако загрузка образа размером в несколько МБ из Интернета не будет повторять ошибку. Тогда я подумал, что, может быть, UIImagePickerController избавляется от изображения, независимо от количества записей! Но копирование изображения также не удалось. Кроме того, как любая из этих вещей может повлиять на представления, которые существуют так же глубоко, как уровень iOS ?! Я исследовал, экспериментировал и гуглил, и никто не сталкивался с этой проблемой, кроме меня ... но я не делаю особо странных! Это проблема Apple? Я забыл что-то очевидное? Я сканировал документацию и руководства безрезультатно, но, возможно, я что-то упустил.

Ничего из этого не сработало:

  • Увеличение счетчика удержания
  • Использование [копия изображения]

Ничего из этого не повторяло проблему с загруженным образом:

  • Уменьшение счетчика удержания
  • Загрузка изображения размером более 1 МБ с большими размерами

Я использую последнюю версию Verizon iPhone с iOS 4.2.8 (базовый SDK «переопределен» до 4.3, что бы это ни значило). 4.2.8 является последней возможной версией для Verizon, хотя 4.3 доступна для iPhone, использующих AT & T.

Вот код в мельчайших деталях. Я еще не проверяю совместимость устройств, но это не должно иметь значения. Возможно, я забыл некоторые настройки с помощью UIImagePickerController?

Краткий обзор: я отображаю лист действий, затем, основываясь на вводе пользователя, отображаю средство выбора изображений. Я сохраняю изображение в качестве преобразуемого атрибута в объекте Core Data (доставка), используя собственный преобразователь. Позже я передаю изображение в контроллер подробного просмотра для отображения пользователю.

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 Ответ

1 голос
/ 22 июля 2011

Я только что разобрался в проблеме, связанной с чрезмерным использованием памяти. Спасибо за этот удивительный пост: https://stackoverflow.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)

Надеюсь, это было полезно!

...