我不明白 Objective-C class 的初始值设定项。

I do not understand Objective-C Initializer for a class.

此代码来自 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 *) 声明参数将是一个 NSString。我假设紧跟在第一个 (NSString *) 之后的单词 title 是参数名称,与 (NSString *) 之后的 artist 相同。 initWithTitle:artist: 是什么?

instancetypeid 的替代品(实际上编译器在编译时将 id 转换为 instancetype 用于 init 方法)或特定类型 class 通常由 init 方法返回,不能在其他任何地方使用。它允许编译器检查来自该 init 方法的赋值是否是适当的类型,同时仍然允许 subclasses 继承初始化器。所以这个 init 方法很可能采用初始值并将它们分配给属性。

它是方法的签名。换句话说..这就是方法命名.

的方式

顺便说一句。 "instancetype" 是一个编译器关键字,表示实例的类型,所以实际上该方法将 return 一个 Song 实例。

- initWithTitle:artist:rating: 是方法的名称,或者用 Objective-C 术语来说,是选择器。 titleartistrating 是参数名称。

至于- (instancetype),减号-表示它是一个实例方法(class方法以加号+开头),而instancetype 是一种 return 类型的方法。它只是一个关键字,告诉编译器此方法将始终 return 调用它的 class 类型的对象。如果你想了解更多,我建议阅读 NSHipster post about instancetype.

你说:

To my understanding, the - (instancetype) creates an instance method, returning an instancetype.

-指定实例方法。 instancetype 是一个特殊关键字,指定它 returns 是 class 的实例,在本例中是 Song 实例。

The two (NSString *)s declare that the parameter will be an NSString.

是的,两个(NSString *)引用表明前两个参数是字符串值。下面的(NSNumber *)表示第三个参数是一个数字object.

I assume that the word title immediately following the first (NSString *) is the parameter name, same with the artist following the (NSString *). What is the initWithTitle: and the 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];

你几乎答对了。

Obj-C 实例方法以连字符“-”开头,后跟括号中的 return 类型。 Class 方法,以加号“+”开头,但其他方面相同。

后面是方法签名的其余部分,可以包含多个参数。每个参数前面都有一个冒号“:”,然后是括号中 argument/parameter 所需的类型,例如NSString *,最后是将传入的值的内部名称。您通过说明每个参数来阅读整个方法名称...

initWithTitle:artist:rating

读成一个句子,你在说:

"Inititialize a Song instance with a title (that's an NSString*), an artist (also an NSString*), and a rating (this requires an NSNumber *)"

-(returnType)firstPartofMethodNameThatTakestheArgument:(NSString *)argument1 andArgumentTwo:(NSString *)argument2

instanceTypeid 的一个相对较新的替代方案,这意味着 return 类型实际上可以是任何类型。这反而确保它只能是包含该方法的类型的实例,在本例中为 Song.

至于重复的参数名称... 第一部分“artist: 是您调用该方法时出现的外部名称(例如,如果您使用代码完成,这就是显示的内容)。参数类型 (NSString *)artist 之后的部分是将在方法实现中使用的 internal 名称。它们可以相同,但不必相同。

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.