2015-07-21 5 views
6

Первый код и выход:ObjectiveC: Странное поведение при использовании NSString и __weak с ARC

NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
__weak NSString *string1; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

Выход:

(null), sunny 

Но после того, как я двигаюсь декларацию о string1 над text, выход отличается , Вот код:

__weak NSString *string1; 
NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

Выход:

sunny, sunny 

Я очень спутать с другим выходом:

  • Почему string0 и string1 отличается в первом случае?
  • Почему выход второго корпуса отличается от первого?
+0

Еще более странным является то, что первая схема дает правильный вывод, если вы запускаете, сохраняя точку останова, а затем выполняете строчную линию. Однако, если вы удаляете контрольную точку, она дает «null». – Gandalf

ответ

6

Попытка выяснить, когда именно объект выпущен или слабое задание может быть сложным, и часто не помогает понять. Вот несколько причин, почему вы можете увидеть различные результаты, чем вы ожидаете:

  • NSString: Лучше никогда использовать этот тип при выполнении такого рода исследований. Строковые литералы бессмертны, они не собираются, и у вас может быть строковый литерал, даже если вы его не ожидаете.
  • Пул авто-релиза: Пул авто-релиза - действительно похмелье от дней до ARC, но оно все еще существует, и многие методы возвращают автоматически выпущенные объекты. Это означает, что многие объекты будут жить дольше, чем вы могли бы ожидать, но не слишком долго. Однако ARC имеет трюки и может удалять объекты из пула авто-релизов раньше, поэтому вы можете подумать, что объект будет жить дольше, а затем он не ...
  • weakссылки: После первых двух пуль вы должны предположите, что, поскольку у вас может не возникнуть реальной идеи, когда объект будет выпущен, если вообще, то у вас может не возникнуть реальной идеи, когда ссылка weak станет нулевой. Просто подумайте «достаточно скоро».
  • Оптимизация: Существует некоторая свобода в оптимизации, которую может выполнить компилятор, который, сохраняя правильную семантику вашей программы, может изменить время жизни объектов.

Если вы хотите запустить такого рода исследования, то вы, вероятно, получите еще больше, если (а) использовать свои собственные типы классов, ничего не из библиотек и (б) использовать @autoreleasepool { ... } блоки для ограничения времени жизни авто -реализованные объекты.

В качестве примера, когда я запустил ваш код на компиляторе, который использовал, я не получил (null), однако изменение первого задания на string0 = text.lowercaseString.mutableCopy действительно произвело один ... Выяснить, почему это осталось в качестве упражнения ...

Имейте вопросительный ум и исследуйте, это хорошо, но будьте готовы к неочевидному!

HTH

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