Переопределить copy или copyWithZone: или оба? - PullRequest
8 голосов
/ 14 февраля 2012

Я запутался, просматривая документацию Apple и читая шаблоны проектирования Какао. В документации Apple для copyWithZone: она гласит:

Этот метод существует, поэтому объекты класса могут использоваться в ситуациях, когда вам нужен объект, который соответствует протоколу NSCopying. За Например, этот метод позволяет использовать объект класса в качестве ключа к NSDictionary объект. Вы не должны переопределять этот метод.

Для copy читается:

Это удобный метод для классов, которые принимают NSCopying протокол. Возникает исключение, если нет реализации для copyWithZone:.

NSObject не поддерживает сам протокол NSCopying. Подклассы должен поддерживать протокол и реализовывать метод copyWithZone:. версия подкласса copyWithZone: метод должен отправить сообщение супер сначала, чтобы включить его реализацию, если подкласс происходит непосредственно от NSObject.

В примерах в шаблонах проектирования какао они переопределяют copyWithZone: и mutableCopyWithZone:, но не переопределяют copy при соответствии протоколу NSCopying. Это то, что я должен делать, если я хочу использовать свой собственный подкласс в NSDictionary в качестве ключа?

Или мне переопределить copy?

Точно так же, если я сделаю [myClass copy], это вызовет copyWithZone: или copy для этого моего пользовательского подкласса? Спасибо.

Ответы [ 2 ]

14 голосов
/ 14 февраля 2012

Все довольно просто: стандартная реализация copy просто вызывает copyWithZone: с аргументом NULL. Поэтому вы всегда должны реализовывать copyWithZone:. Однако, поскольку зоны памяти не используются (насколько я знаю) в iOS, вы должны игнорировать зону, не делая никаких предположений.

Редактировать: чтобы уточнить, вы можете также реализовать copy, но вы должны реализовать copyWithZone:, потому что вы никогда не знаете, какой из них NSDictionary будет вызывать в iOS 6.

0 голосов
/ 15 октября 2015

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

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

Также, как сказано выше, зоны больше не используются вообще, но метод все еще имеет этот параметр для совместимости и исторических причин.

...