This code is from the Sams Teach Yourself Swift book, Chapter 21. The Song.h file contains the following code:
//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
To my understanding, the - (instancetype)
creates an instance method, returning an instancetype
. The two (NSString *)
s declare that the parameter will be an NSString. 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:
?
You pretty much have it correct.
An Obj-C instance method begins with a hyphen, "-" followed by the return type in parentheses. A Class method, begins with a plus "+" but is otherwise the same.
That's followed by the rest of the method signature, which can include multiple parameters. Each parameter is preceded by a colon ":", then the required type for the argument/parameter in parentheses, e.g. NSString *
, which is followed finally an internal name for the value that will be passed in. You read the entire method name by stating each parameter...
initWithTitle:artist:rating
Read as a sentence, you're saying:
"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
The instanceType
is a relatively new alternative for id
which meant the return type could effectively be anything. This instead ensures that it can only be an instance of the type containing the method, in this case a Song
.
As for the duplicate argument names... The first part "artist:
is the external name that appears when you call the method (if you use code completion for example, that's what shows up). The part after the argument's type (NSString *)artist
is the internal name that will be used inside the method implementation. Those can be the same, but they don't have to be.
Swift has a similar construction, but with more options where you can choose to write different internal and external parameter names, or just use 1 (or use in-out parameters whose values chance, use variadic parameters that can be an arbitrary number of elements, etc - look into Swift Functions for more details on those topics).
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.