2010-11-26 2 views
0

Эта проблема полна во многих местах моего кода, но общее поведение таково:
Существует контроллер вида и контроллер detailview. Я создаю объект пользовательского класса в view.This содержит атрибуты типа указателя, такие как строки. Я использую это для инициализации свойства типа пользовательского класса в подробном представлении с использованием метода setter. Но когда я пытаюсь получить доступ к этим свойствам в подробном представлении, я обнаружил, что атрибуты типа указателя объекта либо отображаются как «вне области видимости», либо их тип был изменен на некоторый произвольный тип. Например, когда я отлаживал последний раз , мои свойства nsstring стали CFSet или что-то в этом роде.
Может ли кто-нибудь из них предложить первопричину этой проблемы?Loose scope свойства типа указателя

+0

поделиться своим кодом для лучшего ответа, подумал, что я могу предложить вам проверить, когда вы устанавливаете эти свойства, правильно ли они установлены, я имею в виду правильный тип. – Sanniv 2010-11-26 13:09:36

ответ

2

Если они меняются, вы, вероятно, не сохраняете их.

Для строки, ваша собственность должна выглядеть (в файле .h)

@property (nonatomic, copy) NSString *mString; 

и установить его как

self.mString = [NSString stringWithFormat:@"hello %@", name]; 

, который использует свойство сохранять (или в данном случае скопируйте) строку.

Однако, если вы

mString = [NSString stringWithFormat:@"hello %@", name]; 

вы установили переменную без использования свойства, так что строка не сохраняется - она ​​будет autoreleased в какой-то момент в будущем, и вы будете иметь указатель, который не так указывая на строку больше :)


Зачем использовать копию вместо сохранить для NSStrings?

На самом деле это копия для чего-либо неизменяемого, но имеет изменяемый подкласс (например, NSDictionary, NSArray, NSSet и т. Д.).

Подумайте об этом как о самообороне.

Что произойдет, если у вас есть собственность, как это:

@property (nonatomic, retain) NSArray *things; 

и в своем коде вы используете количество вещей в цикле т.е.

uint max = [things count]; 
for (uint n = 0; n < max; ++n) { ... } 

Хорошо, что должно быть в порядке. Пока кто-то не перейдет в NSMutableArray, а не NSArray. Ваш код предполагает, что, поскольку у вас есть NSArray, количество вещей внутри него не изменится.

Если кто-то удалил элемент из вашего NSArray (потому что это действительно NSMutableArray, но вы этого не знаете), в то время как вы были в этом цикле, ваш код умрет ужасно (исключение за пределы).

Какая копия вместо вызова удержания, она вызывает копирование - 100% уверенность, что внутри вашего объекта у вас есть unmutable array вместо измененного объекта, который кто-то еще прошел. Изменчивый массив можно изменить так же сильно, как они хотите - у вас есть своя собственная копия, чтобы код был безопаснее.

Однако это происходит за счет использования памяти - в памяти есть два массива. Обычно стоит взять память на возможный крах imho :)

NB На самом деле, если кто-то просто прошел в обычном NSArray, потому что он неизменен, реализация [NSArray copy] - это просто сохранение, так что 99/100 раз вы ничего не теряете указав копию для вашего свойства :) - это также верно для всех неизменяемых классов NSxxx.

+0

Я дам вам бонусные баллы, если вы сможете объяснить, почему вы должны использовать копию для NSString (в отличие от сохранения), и когда вы должны использовать удержание вместо копии :) – willcodejavaforfood 2010-11-26 16:03:07

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