16

Я новичок в объективе-c, и я пытаюсь понять управление памятью, чтобы все было правильно.Когда действительно выпущен автореализованный объект?

После прочтения отличной
Memory Management Programming Guide for Cocoa яблоком моя единственная забота, когда фактически autoreleased объект выпущен в 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.

Спасибо!

ответ

17

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

Чтобы ответить на ваш вопрос о том, что такое 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 на объекте, этот объект добавляется в этот пул ауттера в цикле выполнения. Когда текущее событие завершено, пул сливается, и эти объекты, наконец, отправляются сообщения о выпуске.

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

+0

Правильно ли я понимаю, что если бы я не создал никаких пулов автоопределения, все автореализованные переменные останутся в памяти до тех пор, пока приложение не будет закрыто? – Burjua

+0

Вид, системные рамки создают несколько пулов автоопределения для вас в верхней части стека основного потока в таких методах, как UIApplicationMain(). Однако, если вы запустили свой собственный поток и не создали пул, тогда да, эти объекты будут течь. В этом случае метод автоопределения регистрируется на консоли. –

+0

Хорошо, но это странно, это обычная практика использования конструкторов, которые возвращают объекты с автореализацией и не выпускают их, но на самом деле это то же самое, что и утечка памяти (память распределяется до закрытия приложения). Или я что-то не понимаю? – Burjua

0

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

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

+3

«Пропустил стек», вероятно, не лучший выбор фразы, потому что он подразумевает, что стек используется для возвращаемых значений, что не всегда так. –

Смежные вопросы