Objective-C, методы владения и класса

Во-первых, я новичок в Objective-C. :)

Я узнал, что все, что начинается с alloc, new и copy, дает вызывающей стороне право собственности на возвращаемый объект. Это относится и к методам класса? Я предполагаю, что да, и недавний сбой в одном из моих модульных тестов, кажется, подтверждает это. В Руководстве по программированию расширенного управления памятью Apple ничего не говорится о том, есть ли разница между методами класса и экземпляра.

Обновление То, что я имею в виду, применимо и к методам класса, на самом деле является «обратным». Например, NSDecimalNumber имеет метод класса с именем +decimalNumberWithDecimal:. Кажется, он возвращает автоматически выпущенный объект (если я его выпускаю явно, вскоре после этого происходит сбой). Оглядываясь назад, ответ на мой вопрос очевиден, поскольку руководство Apple называет new и alloc методами передачи прав собственности, и все они являются методами класса. Извините, что отнял ваше драгоценное время. :)


person Jörgen Sigvardsson    schedule 12.12.2011    source источник
comment
Вы имеете в виду метод класса, который генерирует для вас объект? Да, конечно. Этот шаблон является одним из ключей управления памятью в obj-c. К этому шаблону применимы даже неяблочные фреймворки.   -  person yinkou    schedule 13.12.2011


Ответы (3)


Также alloc и release. init не указывает на право собственности, вы, вероятно, путаете это с alloc. Вы можете легко запомнить его с помощью мнемоники NARC.

Если вы называете какие-либо методы класса init, copy или retain, вы должны прекратить это. Это методы, которые имеют смысл только в контексте экземпляров. alloc и new являются методами класса и должны использоваться только в этом контексте. Не называйте методы экземпляра alloc или new.

Причина, по которой в руководстве не говорится, что это применимо как к методам экземпляра, так и к методам класса, заключается в том, что рассматриваемые методы явно представляют собой смесь обоих, так что это очевидно.

person Jim    schedule 12.12.2011
comment
Да, я перепутал init с new! :) - person Jörgen Sigvardsson; 13.12.2011

Да, это относится к методам класса, поскольку alloc и new являются методами класса, которые возвращают право собственности вызывающей стороне. Префикс copy или mutableCopy следует использовать для методов экземпляра, возвращающих право собственности.

Изменить для обновления:

Вы правы, ожидается, что такой метод, как +decimalNumberWithDecimal:, вернет автоматически выпущенный объект, поэтому нет причин его выпускать. Однако, если они решили назвать метод +newNumberWithDecimal:, тогда вы будете владельцем возвращаемого объекта и должны будете его освободить. Статический анализатор Clang на самом деле будет жаловаться, если вы укажете метод с префиксом new и вернете автоматически выпущенный объект.

person Joe    schedule 12.12.2011
comment
@JeffWolski: в руководствах по программированию Apple прямо упоминаются copy (и варианты) как методы, дающие право собственности. См. здесь: developer.apple.com/ библиотека/mac/#documentation/Cocoa/Conceptual/ - person Jörgen Sigvardsson; 13.12.2011

На самом деле, это почти правильно. alloc, new и copy дают вам право собственности на возвращаемый объект. Это методы класса. Другие методы класса должны возвращать автоматически выпущенный объект. Методы экземпляра также должны возвращать автоматически выпущенный объект.

init не влияет на право собственности и должен использоваться вместе с alloc следующим образом.

[[SomeCoolClass alloc] init]

new обычно то же самое, что и выше, и иногда описывается как «почти устаревший», потому что это возврат к дням NeXT, когда выделение и инициализация выполнялись на одном этапе и не могли быть разделены, как мы делаем сегодня с alloc и init.

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

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

person Jeff Wolski    schedule 12.12.2011