В приведенном ниже коде я пытаюсь использовать метод init, который можно вызывать статически, поскольку считаю, что метод инициализации должен быть ответственностью класса.
Существуетопределенное «семейство» методов для методов инициализации класса, так же, как методы инициализации экземпляра начинаются с init
, методы класса начинаются с new
. Существует реализация по умолчанию new
и ее документация состояний:
Этот метод представляет собой комбинацию alloc
и init
. Как и alloc
, он инициализирует переменную экземпляра isa нового объекта, поэтому он указывает на структуру данных класса. Затем он вызывает метод init
для завершения процесса инициализации.
Чтобы определить свой метод, следуйте тому же шаблону, который вы обычно используете для определения пользовательского метода init
: вы вызываете его new...
и вызовите new
для создания объекта, который вы специализируете:
+(instancetype) newWithName:(NSString *)synchName andId:(NSString *)synchId
{
Synchron *synch;
synch = [self new]; // any call to new or alloc/init may return nil
if (synch) // so check before setting the properties
{
synch.synchronName = synchName;
synch.synchronId = synchId;
}
return synch;
}
Примечания: вышеизложенное изменило три вещи по сравнению с вашим кодом
Имена свойств начинаются со строчной буквы в соответствии со стандартным соглашением об именах.
Тип возвращаемого значения был изменен на instancetype
. Это новое ключевое слово было добавлено в Objective-C для повышения безопасности типов. Он используется, когда метод возвращает экземпляр своего класса, например, методы инициализации и фабрики, и позволяет лучше предупреждать компилятор. Подробности его точного значения см. В разделе instancetype в Принятие Modern Objective-C . Вы все равно увидите, что id
используется много.
self
используется вместо Synchron
в вызове new
. В методе класса self
относится к классу (а не к экземпляру, как в методе экземпляра), к которому был вызван метод. Это изменение поддерживает случай, когда метод был вызван из подкласса Synchron
и, следовательно, self
относится к этому подклассу.
Кредит: изменения 2 и 3 былиПервоначально опущено, чтобы упростить ответ, но комментарии @Rob к нескольким ответам побудили нас включить их для полноты. (Ваш код «работает» без этих изменений.)
Этот метод имеет ту же семантику возврата, что и alloc
/ init
, и возвращаемое значение принадлежит вызывающей стороне и ееВремя жизни будет управляться ARC (автоматический подсчет ссылок). Подробнее о семействах методов см. В разделе Семейства методов в документации ARC.
Эра до ARC
В эру до ARCкогда вам приходилось вручную управлять временем жизни объекта - известным как MRR (ручное сохранение выпуска) или MRC (ручной подсчет ссылок), семейство методов new
использовалось меньше. Вместо фабричных методов в соответствии с соглашением об именах <classname>...
, в вашем случае этот метод был бы следующим:
+(id) synchronWithName:(NSString *)synchName andId:(NSString *)synchId
Такой метод не входит в семейства new
или init
и поэтому возвращает неизвестную ссылкувызывающему абоненту, и ARC должен справиться с этим немного по-другому. Важно: , поскольку его название подразумевает ARC, Автоматический Подсчет ссылок, будет обрабатывать такой фабричный метод без необходимости беспокоиться о различной семантике возвращаемого значения, однако кодпроизведенный будет очень незначительно менее эффективен.
Тело фабричного метода может быть точно таким же, как у new
семейного метода, хотя было бы более распространенным использовать alloc
/ init
для создания объекта:
+(instancetype) synchronWithName:(NSString *)synchName andId:(NSString *)synchId
{
Synchron *synch;
synch = [[self alloc] init];
if (synch)
{
synch.synchronName = synchName;
synch.synchronId = synchId;
}
return synch;
}
Pick Your Style
Вы увидите множество фабричных методов <classname>...
вокруг и, вероятно, довольнонесколько меньше методов инициализации класса new...
. ARC обрабатывает и автоматически, и разница в эффективности, скорее всего, будет незначительной для вашего кода ( никогда преждевременно оптимизировать, т. Е. Не тратить на это время, если у вас нет проблем - но в то же время нетнапишите намеренно плохо исполняемый код!).
Независимо от того, используете ли вы заводской стиль или семейный стиль new
, нет правильного или неправильного.
HTH