Когда действительно выпущен автореализованный объект?

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

После прочтения превосходного Руководство по программированию управления памятью для Cocoa 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.

Спасибо!

Ответы

Ответ 1

Да, ваши функции действительны и возвращают объекты, используя правильные соглашения Cocoa для сохранения/освобождения/автоматического оповещения/копирования.

Чтобы ответить на ваш вопрос о том, что такое 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];
    }
}

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

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

Ответ 2

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

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