new方法的內部就是先調用alloc方法,再調用init方法測試
alloc方法:那個類接受alloc消息,那麼該方法返回該接受類的對象,並把對象返回指針
init方法:是1個對象方法,做用:初始化對象code
建立對象的步驟:先使用alloc建立1個對象,再使用init初始化這個對象,纔可使用這個對象對象
init方法:做用:初始化對象,爲對象賦初始值,叫作構造方法編譯器
若是想建立出來的對象的屬性值不是默認的初始化值,則須要重寫init方法it
重寫init方法的規範:io
必需要先調用父類的init方法(由於當前類初始化就是經過`[父類init]`去初始化),而後將返回值賦值給self編譯
調用init方法有可能會失敗,若是失敗直接返回nilimport
判斷父類是否初始化成功。若是self != nil,則表明初始化成功方法
若是初始化成功就去初始化當前對象的屬性
最後返回self
-(instancetype)init{ if (self = [super init]) { //todo:自定義屬性的初始化 } return self; }
//Person #import <Foundation/Foundation.h> @interface Person : NSObject @property NSString* name; @property int age; -(void)sayHi; @end #import "Person.h" @implementation Person -(void)sayHi{ NSLog(@"Hi"); } -(instancetype)init{ self = [super init]; if (self) { self.name = @"杭城小劉"; self.age = 22; } return self; } @end //測試 Person *p1 = [[Person alloc] init]; //p1.name = "杭城小劉",p1.age =22; Person *p2 = [Person new]; //p2.name = "杭城小劉",p2.age =22;
若是2個類的關係爲組合關係,且它的一個屬性是另外一個類的對象,那麼當該類初始化的時候默認它的屬性爲nil,那麼如何初始化?
-(instancetype)init{ self = [super init]; if (self) { self.name = @"lbp"; self.age = 22; self.pig = [[Pig alloc] init]; } return self; } //測試 Person *p1 = [[Person alloc] init]; //p1.dog != nil
現狀:雖然每次雙肩的對象的屬性值不是默認的,可是每次初始化的對象的值都是同樣的。
需求:每次實例化的對象的屬性值由調用者決定
解決辦法:自定義構造方法
自定義構造方法規範:
自定義構造方法的返回值爲instancetype
方法的命名必須以initWith開頭
方法的實現相似init的實現
注意:此時不能使用new來調用。(由於new的實現是先alloc再init,默認init的實現是給屬性賦默認值)
-(instancetype)initWithName:(NSString *)name andAge:(int)age{ if (self = [super init]) { self.name = name; self.age = age; } return self; }
//Person #import <Foundation/Foundation.h> @interface Person : NSObject @property NSString* name; @property int age; -(instancetype)initWithName:(NSString *)name andAge:(int)age; @end #import "Person.h" @implementation Person -(instancetype)init{ self = [super init]; if (self) { self.name = @"lbp"; self.age = 22; } return self; } //不能在構造方法以外給self賦值 //編譯器認爲只有以initWith開頭的方法是構造方法 -(instancetype)initWithName:(NSString *)name andAge:(int)age{ if (self = [super init]) { self.name = name; self.age = age; } return self; } @end //測試 Person *p1 = [[Person alloc] init]; Person *p2 = [Person new]; Person *p3 = [[Person alloc] initWithName:@"杭城小劉2號" andAge:23];
關於「自定義構造方法必須以initWith開頭」作個實驗
報錯信息很明顯:不能在構造方法以外給self賦值
由於,編譯器認爲只有以initWith開頭的方法是構造方法