Я не понимаю Objective-C Initializer для класса.
Этот код взят из книги Sams Teach Yourself Swift, глава 21. Файл Song.h содержит следующий код:
//Song.h
#import <Foundation/Foundation.h>
@interface Song : NSObject;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *artist;
@property (nonatomic, strong) NSNumber *rating;
- (instancetype)initWithTitle:(NSString *)title artist:(NSString *)artist rating:(NSNumber *)number;
@end
Насколько я понимаю, - (instancetype)
создает метод экземпляра, возвращая instancetype
, Два (NSString *)
s объявляют, что параметр будет строкой NSString. Я предполагаю, что слово title
сразу после первого (NSString *)
имя параметра, то же самое с artist
следуя (NSString *)
, Что initWithTitle:
и artist:
?
5 ответов
Вы в значительной степени поняли это правильно.
Метод экземпляра Obj-C начинается с дефиса, "-", за которым следует тип возврата в скобках. Метод класса, начинается с плюса "+", но в остальном тот же.
Далее следует подпись метода, которая может включать несколько параметров. Каждому параметру предшествует двоеточие ":", затем требуемый тип для аргумента / параметра в скобках, например NSString *
, за которым следует, наконец, внутреннее имя для значения, которое будет передано. Вы прочитали полное имя метода, указав каждый параметр...
initWithTitle:artist:rating
Прочитайте как предложение, вы говорите:
"Инициализировать экземпляр Song с названием (это NSString*), исполнителем (также NSString *) и рейтингом (для этого требуется NSNumber *)"
-(returnType)firstPartofMethodNameThatTakestheArgument:(NSString *)argument1 andArgumentTwo:(NSString *)argument2
instanceType
это относительно новая альтернатива id
что означало, что тип возвращаемого значения может быть любым. Это гарантирует, что это может быть только экземпляр типа, содержащего метод, в этом случае Song
,
Что касается повторяющихся имен аргументов... Первая часть "artist:
это внешнее имя, которое появляется при вызове метода (например, если вы используете завершение кода, это то, что отображается). Часть после типа аргумента (NSString *)artist
это внутреннее имя, которое будет использоваться внутри реализации метода. Те могут быть одинаковыми, но они не должны быть.
Swift имеет аналогичную конструкцию, но с большим количеством опций, в которых вы можете написать разные внутренние и внешние имена параметров или просто использовать 1 (или использовать входные-параметры, значения которых могут быть случайными, использовать переменные параметры, которые могут быть произвольным числом элементов, и т. д. - смотрите Swift Functions для более подробной информации по этим темам)
func initWith(externalTitle internalTitle:String, #artist:String, #rating:Int) -> Song
//When calling, you'd see "externalTitle:artist:rating"
//but in the method implementation you'd use "internalTitle" instead.
- initWithTitle:artist:rating:
это имя метода или, в терминах Objective-C, селектор. title
, artist
а также rating
являются именами параметров.
Что касается - (instancetype)
знак минус -
означает, что это метод экземпляра (методы класса начинаются со знака плюс +
), в то время как instancetype
является типом возврата метода. Это просто ключевое слово, которое сообщает компилятору, что этот метод всегда будет возвращать объект типа класса, для которого он был вызван. Если вы хотите узнать больше об этом, я предлагаю прочитать сообщение NSHipster об instancetype.
Это подпись метода. Другими словами... так называется метод.
Btw. "instancetype" - это ключевое слово компилятора, представляющее тип экземпляра, поэтому на самом деле метод возвращает экземпляр Song.
Вы сказали:
Насколько я понимаю,
- (instancetype)
создает метод экземпляра, возвращаяinstancetype
,
-
обозначает метод экземпляра. instancetype
специальное ключевое слово, обозначающее, что оно возвращает экземпляр класса, Song
экземпляр в этом случае.
Два
(NSString *)
s объявляют, что параметр будетNSString
,
Да, два (NSString *)
ссылки указывают, что первые два параметра являются строковыми значениями. Следующие (NSNumber *)
указывает, что третий параметр является числовым объектом.
Я предполагаю, что слово заголовок сразу после первого
(NSString *)
имя параметра, то же самое с артистом, следующим за(NSString *)
, ЧтоinitWithTitle:
иartist:
?
Слово сразу после (NSString *)
это имя параметра, используемого в реализации этого метода.
Рассмотрим декларацию:
- (instancetype)initWithTitle:(NSString *)title artist:(NSString *)artist rating:(NSNumber *)number;
Это объявляет метод с именем initWithTitle:artist:rating:
, который принимает три параметра, название, исполнителя и рейтинг. Поэтому, если вы хотите создать песню под названием "Ticket to Ride" с помощью "Beatles" с рейтингом 5, вы бы назвали этот метод примерно так:
Song *song = [[Song alloc] initWithTitle:@"Ticket to Ride" artist:@"Beatles" rating:@5];
instancetype
замена для id
(и на самом деле компилятор покрывает id
в instancetype
для методов init во время компиляции) или класс определенного типа, который обычно возвращается методами init и не может использоваться где-либо еще. Это позволяет компилятору проверять, являются ли назначения из этого метода init подходящим типом, в то же время позволяя подклассам наследовать инициализаторы. Так что этот метод init, скорее всего, принимает начальные значения и присваивает их свойствам.