Как удалить подпредставление из памяти при возврате в основной вид? - PullRequest
0 голосов
/ 03 сентября 2011

Предположим, у меня есть основное окно, когда я нажимаю на кнопку, оно загружает подпредставление и позволяет этому подпредставлению запустить фонарик (светодиод), а затем, когда я вернусь к основному виду, оно выпустит вспомогательное представление и выключитфонарик (светодиод)

- (void)loadView
{
    [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // If torch supported, add button to toggle flashlight on/off
    if ([device hasTorch] == YES)
    {  
        // Create an AV session
        AVCaptureSession *session = [[AVCaptureSession alloc] init];

        // Create device input and add to current session
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
        [session addInput:input];

        // Create video output and add to current session
        AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
        [session addOutput:output];

        // Start session configuration
        [session beginConfiguration];
        [device lockForConfiguration:nil];

        // Set torch to on
        [device setTorchMode:AVCaptureTorchModeOn];

        [device unlockForConfiguration];
        [session commitConfiguration];

        // Start the session
        [session startRunning];

        // Keep the session around
        [self setAVSession:session];

        [output release];

    }
}

Теперь, когда я закрываю подпредставление, оно должно освободить его из памяти и остановить фонарик.

- (void)viewDidUnload
{
    [self.view removeFromSuperview];
    [self autorelease];
    [AVSession stopRunning];
    [AVSession release], AVSession = nil;
    [super viewDidUnload];
}

Но эта вещь viewDidUnload не работает, пожалуйста, сообщитемне, что я делаю не так.

Ответы [ 2 ]

3 голосов
/ 04 сентября 2011

Проблема в том, что вы неправильно поняли цель -viewDidLoad.

-viewDidUnload вызывается только в случаях нехватки памяти, когда система пытается освободить память. В этом случае неактивные контроллеры представлений освободят свои представления и вызовут -viewDidUnload, чтобы вы могли освободить любые связанные с представлением ресурсы.

Не рассчитывайте на то, что -viewDidUnload вызывается, когда контроллер представления становится неактивным или когда контроллер представления освобождается.

Ваш контроллер представления, по-видимому, знает, когда AVSession должен быть завершен, и он может завершить сеанс всякий раз, когда он это выяснит.

Кстати, хорошо, что ваш -viewDidUnload никогда не бежал; звонок на [self autorelease], вероятно, привел бы к краху. Зачем ты это делаешь? Код, который вы показали, является частью контроллера представления. Я не знаю, как называется этот класс, поэтому я представлю, что это FlashlightViewController. Предположительно, какой-то другой контроллер представления создает экземпляр FlashlightViewController и каким-то образом делает его активным, например:

FlashlightViewController *fvc = [[FlashlightViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:fvc];
[fvc release];

Здесь контроллер навигации будет сохранять fvc при его нажатии, и контроллер, создавший fvc, освобождает его, потому что ему больше не нужна ссылка на новый контроллер. Когда контроллер фонаря закончил свою работу и извлечен из стека навигации, контроллер навигации освободит его. Поскольку никакой другой объект не сохранил контроллер фонарика, он будет автоматически освобожден. Когда это произойдет, он освободит свой вид, и, поскольку ни один другой объект не сохранил вид, вид также будет освобожден.

Детали вашей ситуации могут отличаться, но идея всегда одна и та же: контроллер представления и представление будут удалены из памяти после освобождения контроллера представления.

2 голосов
/ 04 сентября 2011

Скорее всего, вы сохраняете контроллер представления, и он решает сохранить представление в памяти на тот случай, если ваше приложение решит отобразить его снова (это кэширование, которое Калеб упоминает в комментарии). То, что представление не видно, не означает, что оно будет выгружено.

Если у вас есть утечка памяти (а здесь я имею в виду VC), очевидно, имеет смысл ее исправить.

Тем не менее, я думаю, что ваш лучший вариант для включения и выключения фонарика - это делать это в viewDidAppear и viewDidDisappear (или их ..will .. вариантах).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...