Когда автоматически выпущенный объект действительно выпущен? - PullRequest
16 голосов
/ 23 марта 2010

Я новичок в target-c и пытаюсь понять, как правильно управлять памятью.

После прочтения превосходного
Руководства по программированию управления памятью для какао от appleЕдинственное, что меня беспокоит, это когда автоматически выпущенный объект выпускается в приложении iphone / ipod.Насколько я понимаю, в конце цикла выполнения .Но что определяет цикл выполнения в приложении?

Поэтому мне было интересно, прав ли следующий фрагмент кода.Предположим, объект

@implementation Test

- (NSString *) functionA {
    NSString *stringA;
    stringA = [[[NSString alloc] initWithString:@"Hello"] autorelease]
    return stringA;
}

- (NSString *) functionB {
    NSString *stringB;
    stringB = [self functionA];
    return stringB;
}

- (NSString *) functionC {
    NSString *stringC;
    stringC = [self functionB];
    return stringC;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString* p = [self functionC];
    NSLog(@"string is %@",p);
}

@end

Этот код действителен?

Из текста яблока я понимаю, что строка NSString, возвращенная из functionA , действительна в области действия functionB .Я не уверен, допустимо ли это в functionC и в viewDidLoad .

Спасибо!

Ответы [ 2 ]

17 голосов
/ 23 марта 2010

Да, ваши функции действительны и возвращают объекты, используя правильные соглашения Какао для retain / release / autorelease / copy.

Чтобы ответить на ваш вопрос о том, что такое runloop, в функции main () вашего приложения,он вызывает UIApplicationMain ().Вы можете себе представить, что UIApplicationMain выглядит примерно так:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) {
    UIApplication *app = /* create app using principalClassName */;
    [app setDelegate:/* create delegate using delegateClassName */];
    while (![app shouldTerminate]) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        event = [app getNextEvent];
        [app dispatchEvent:event];
        [pool drain];
    }
}

То, что циклы while похожи на то, что на самом деле делает UIKit, и каждое отключение этого цикла while похоже на отключение в runloop, где функция getNextEventблоки в ожидании какого-то события.Все ваши методы обычно вызываются из чего-то вроде dispatchEvent :.Вы можете попытаться установить точку останова в одном из ваших методов, например, IBAction, и посмотреть в стеке вызовов отладчика вверх, чтобы увидеть имена методов UIKit, которые обрабатывают события и цикл выполнения.Поскольку каждый из ваших методов вызывается из цикла while, каждый раз, когда вы вызываете autorelease для объекта, этот объект добавляется в пул outter в цикле выполнения.Когда текущее событие заканчивается отправкой, пул очищается, и этим объектам наконец отправляются сообщения об освобождении.

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

0 голосов
/ 23 марта 2010

В этом коде нет ничего плохого. Он будет скомпилирован и запущен, как вы ожидаете.

Объект NSString, возвращаемый из functionA, по-прежнему действителен при возврате, поскольку он передается по стеку следующему парню (functionB), который теперь отслеживает его.

...