Вам необходимо прочитать Руководство по управлению памятью какао .
Некоторые вещи, которые вы делаете в коде, показывают, что вы не понимаете фундаментальных концепций управления памятью какао.
Например:
[Foo alloc];
Вы не инициализируете 'foo'. Обычной практикой является объединение вызовов alloc
и init
вместе, например: [[Foo alloc] init];
Это обеспечит то, что члены и состояние объектов соответствуют вашим ожиданиям после создания.
name2 = [foo bar]; // returns a (NSString *)
Метод bar
может возвращать строку autoreleased
. Вы не сохраните его после присвоения name2
, поэтому он будет освобожден через некоторое время после возврата метода. И именно поэтому ваш код падает. Вы пытаетесь получить доступ к освобожденному объекту. Объект, на который указывал name2
, был освобожден и освобожден, но указатель не был установлен равным nil, что означает, что память, на которую он указывает, теперь может содержать все что угодно. Это не определено.
Причина, по которой name1
работает, заключается в том, что особое внимание уделяется использованию буквенных @ "" строк в Какао. Когда строка используется таким образом, она становится «интернализованной». Если вы создадите две литеральные строки, содержащие один и тот же текст, система оптимизирует его так, чтобы обе эти строки указывали на один объект в памяти.
То есть, если у вас есть код, который выглядит следующим образом:
NSString *myString1 = @"hello";
NSString *myString2 = @"hello";
NSLog(@"string1: %p, string2: %p", myString1, myString2);
это приведет к тому, что сообщение будет выглядеть так: string1: 0x123456, string2: 0x123456
. Здесь важно отметить, что адреса памяти одинаковы. Строки указывают на один и тот же объект, хотя в коде они являются разными экземплярами.