0

Я использую SBJson для разбора строк JSON.ARC и метод «copy»

Как это:

NSDictionary *dict = received_notification.object; 

Должен ли я использовать

NSString *name = [[dict valueForKey:@"name"] copy]; 

или

NSString *name = [dict valueForKey:@"name"]; 

Я думаю, что первые экземпляры метода NSString и после этого Словаря могут быть освобождены.

Но для второго выражения «имя» хранит ссылку на dict и не может быть выпущено.

Я не прав?

+4

@ CodenameLambda1 Нет, он не прав, я пишу ответ – LombaX

+5

Обратите внимание, что 'objectForKey:' является основным методом для получения значений словаря. 'valueForKey:' используется только для магии кодирования ключа. –

+0

@MartinR вы правы, я добавил его в свой ответ (с «credit» :-) – LombaX

ответ

7

Вы правы в первом случае, и копирование может быть полезным, поскольку NSString имеет изменяемый подкласс (NSMutableString), так copy гарантирует, что у вас есть в *name реальной NSString и не это изменчивый подкласс.
(Подробнее: Говоря о NSString, copy используется в основном по свойствам, но в зависимости от того, как структурирован ваш код может быть полезным даже в локальной переменной)

Но во втором случае вы не правы. Первого: вы используете ARC (не упоминается в этой должности, но я вижу тег), так что все локальные переменные являются __strong по умолчанию

Когда вы делаете:

NSString *name = [dict objectForKey:@"name"]; // use objectForKey since valueForKey is for KVC, as suggested by Martin R 

Вы не принимаете ссылку в словарь, но вы делаете ссылку на объект в ключевом «имени» внутри словаря (это должно быть NSString). Итак, ARC автоматически отправляет сообщение retain на номер NSString. В тот момент, что строка сильно по крайней мере ссылается две вещи:
- ваш *name указатель
- NSDictionary

если ваш словарь высвобождены, экземпляр NSString имеет другую ссылку (от *name) и не освобождается, пока эта последняя ссылка не будет удалена.

Последнее: поскольку в вашем примере есть только локальные переменные, все сильные ссылки, созданные здесь, теряются после завершения метода (поскольку локальные переменные уничтожаются). Объекты, на которые ссылаются, освобождаются, если у них нет других сильных ссылок в других частях кода.

+0

Хорошо объяснил. –

+0

Спасибо. Поэтому я могу просто избежать «копирования» в моем примере выше и не беспокоиться о памяти? Тогда я помещаю «имя» в свою базу данных, и через некоторое время я заменяю данные. – SevenDays

+0

Если вы уверены, что переданное значение является NSString (и не может быть NSMutableString), вы можете избежать копирования.Но я не понимаю, что вы имеете в виду в своем втором вопросе :-) если вы делаете 'NSString * name = [dict objectForKey: @" name "];' и после, заменяете содержимое * dict, содержимое * имя сохраняется. Однако, поскольку вы используете локальные переменные, содержимое сохраняется до тех пор, пока не вернется текущий метод. Если вы хотите, чтобы ссылка сохранялась, вы должны использовать переменную экземпляра. – LombaX