Помните, что alloc
возвращает принадлежащий вам объект.
Если вы объявили свои три строковых свойства как retain
, назначение этих объектов вашим свойствам означает, что теперь вы владеете каждым из них дважды - один раз, потому что вы его заблокировали, и снова, потому что вы присвоили его своему свойству. Объекты остаются живыми, потому что ничто не освобождает их вторых владельцев.
Если вы объявили свойства как copy
(что является правильным способом объявления свойства NSString), то при назначении объекта там сохраняется копия в качестве значения свойства. Вы больше ничего не делаете с оригинальными объектами, которые остаются живыми, потому что ничто не освобождает их.
В любом случае, это ваша утечка.
Свойство должно быть объявлено как copy
; если это уже так, не пытайтесь исправить утечку, изменив ее.
Вы не должны использовать доступ к собственности здесь. Помните, что присвоение свойству - это сообщение set<PropertyName>:
, и ваш объект еще не полностью инициализирован. Отправка сообщения не полностью инициализированному или не полностью освобожденному объекту вызывает проблемы, особенно когда задействованы подклассы, поскольку они могут переопределять методы доступа так, как этого не ожидает суперкласс.
Таким образом, только в init
присваивайте непосредственно переменным экземпляра. Только в dealloc
отправляйте release
сообщения непосредственно объектам в переменных экземпляра. Везде, где угодно, используйте доступ к свойствам.
Вы также не должны использовать alloc
и initWithString:
здесь. Это будет работать, но соглашение состоит в том, чтобы отправлять copy
сообщений объектам, которые у вас уже есть, так же, как и свойства. Отправьте copy
сообщения вашим входным строковым объектам, затем назначьте копии переменным вашего экземпляра.
Когда вы используете доступ к свойству, используйте вспомогательные конструкторы (например, stringWith…:
), так как они возвращают объекты, которыми вы не владеете. Когда вы присваиваете эти объекты вашим объявленным copy
свойствам, вы фактически будете хранить копии, которые у вас есть.
Другой способ - использовать alloc
и initWithWhatever:
, а затем немедленно autorelease
этот объект, прежде чем присваивать его свойству; таким образом создается объект, которым вы владеете, а затем сразу же отказывается от владения, прежде чем назначить его свойству.