В Какао у вас есть объект, только если вы создаете его с помощью alloc
, new
, copy
или retain
. Всякий раз, когда вы не владеете объектом, у вас нет никаких гарантий относительно этого объекта за пределами локальной области, в которой вы его используете. В вашем примере, поскольку вы не создали новую строку ни с одним из вышеупомянутых методов, у вас нет гарантии, что она появится позже, если вы ее сохраните.
Для того, чтобы стать владельцем объекта (т. Е. Вы хотите, чтобы он оставался вокруг, чтобы вы могли использовать его позже), которым вы еще не владеете (т. Е. Вы не создали его, используя один из ранее упомянутые методы), вы должны отправить этот объект сообщение сохранения. Например, если вы переписываете свой код, как показано ниже, вам будет принадлежать строка, и вам не придется беспокоиться об ее использовании позже:
// option 1
NSString *path = [[NSBundle mainBundle] pathForResource:@"foo" ofType:@"txt"];
NSString *string = [[NSString alloc] initWithContentsOfFile:path encoding:NSASCIIStringEncoding error:NULL];
// option 2
NSString *path = [[NSBundle mainBundle] pathForResource:@"foo" ofType:@"txt"];
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:NULL];
[string retain];
Вариант 1 приемлем, потому что вы специально создаете строку с сообщением alloc
. Теперь вы владеете строковым объектом, пока не откажетесь от владения в другое время. Это, вероятно, лучший вариант для вас, учитывая ваши конкретные обстоятельства (то есть вы не хотите использовать удобный конструктор, потому что хотите, чтобы строковый объект зависал, чтобы использоваться позже).
Вариант 2 приемлем, потому что вы определенно вступаете во владение строкой, отправляя ей retain
. В вашем случае это, вероятно, не лучший вариант, потому что уже есть опция alloc/init
, которую обычно легче читать.
Когда вы закончили с объектом и хотите отказаться от владения этим объектом, вы отправляете этому объекту сообщение release
. Важно помнить, что в Какао отправка объекту сообщения release
не означает, что вы его уничтожаете, просто отказываетесь от владения.
Управление памятью какао основано на идее владения объектами. Хотя поначалу это может показаться немного запутанным, но когда вы обернетесь вокруг него, это значительно упростит программирование в среде без ошибок памяти, утечек или других ошибок. Методы удобства (например, stringWithString
) действительно предназначены для использования, когда вы хотите создать объект, который вы действительно используете только в течение короткого периода времени и в рамках одной функции или программного блока. Если вы планируете держать объект за пределами этой области, предпочтительнее использовать методы alloc/init
или new
для создания объекта.
Для получения дополнительной информации, пожалуйста, прочитайте Руководство по программированию управления памятью для какао . Это действительно считается обязательным чтением для разработчиков какао. Кроме того, обычно требуется его чтение, эксперименты и чтение еще несколько раз, чтобы понять, особенно если у вас есть большой опыт работы с другими моделями управления памятью.