對象的alloc+init
專業(yè)領(lǐng)域包括做網(wǎng)站、成都網(wǎng)站建設(shè)、成都商城網(wǎng)站開發(fā)、微信營銷、系統(tǒng)平臺開發(fā), 與其他網(wǎng)站設(shè)計及系統(tǒng)開發(fā)公司不同,成都創(chuàng)新互聯(lián)公司的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。
類對象的new方法可以創(chuàng)建一個屬性均為0的對象
new方法實際上是兩個方法的連續(xù)調(diào)用:
1)分配存儲空間 alloc 類對象方法
2)初始化 init 對象方法
也就是說 Person *p = [Person new]; 等同于: Person *p = [[Person alloc] init];
alloc和init方法都是NSObject的方法,故所有的OC類型都可以使用這種方式創(chuàng)建對象
init方法:
- (instancetype)init
該方法的默認操作:調(diào)用父類的init方法,并返回對象本身,成員變量的初值為0
重寫init方法
默認的init方法,將對象的屬性初值設(shè)為0,如果我們想要指定一個初值,就需要重寫該方法。
NSObject的子類重寫init方法的步驟:
1. 調(diào)用父類的init方法,將其父類中的屬性初始化
2. 為子類的屬性初始化
3. 返回對象本身
重寫init方法一般形式:
如:Person類,包含一個屬性_age
- (instancetype) init { if ( self = [super init] ) { _age = 10; } return self; }
再如:Person的子類Student,包含一個屬性score
- (instancetype) init { if ( self = [super init] ) {//調(diào)用了父類Person的init函數(shù) _score = 1; } return self }
init方法是一層一層往下調(diào)用的
重寫構(gòu)造方法的目的是為了對象創(chuàng)建出來,成員變量就會有一些規(guī)定的值
自定義init方法
默認的Init方法不帶參數(shù),只能為對象初始化一些固定值
通過自定義init方法可以實現(xiàn)通過參數(shù)初始化對象屬性。
返回值一般是instancetype類型
方法名以initWith開頭
如Person類中包含屬性name和age
- (instancetype) initWithName:(NSString *) name { if ( self = [super init] ) { _name = name; } return self; } - (instancetype) initWithName:(NSString*)name age:(int) age { if ( self = [super init] ) { _name = name; _age = age; } }
子類的init方法應(yīng)指定調(diào)用父類的哪個init方法
如Person子類Student類:
- (instancetype) initWithName:(NSString *)name age:(int) age score:(int) score { if ( self = [super initWithName:name age:age] ) { //也可以用super的init方法及set方法,但不推薦 _score = score; } return self; }
有時我們需要創(chuàng)建一個現(xiàn)有對象的副本,則應(yīng)編寫一個拷貝構(gòu)造方法,參數(shù)為對象指針
- (instancetype) initWithPerson:(Person*) p { if ( self = [super init] ) { _age = p.age; _name = p.name; } return self; }
一個對象銷毀時,會調(diào)用一個dealloc方法
- (void)dealloc
該方法在最后應(yīng)調(diào)用父類的dealloc方法
dealloc方法不能直接調(diào)用
需要注意的是,在引入ARC機制后,重寫這個方法時不能調(diào)用父類被重寫的dealloc方法
類對象
我們定義的類也是一種對象 ,是Class類的對象
Class創(chuàng)建Person類對象,再通過Person類對象方法來創(chuàng)建對象。
這里:類對象 == 類
之前說過,每個對象都一個isa指針,isa指針指向就是類對象
方法的調(diào)用過程:
實際上就是通過基類部分的isa屬性,找到成員函數(shù)列表,再將消息傳遞的參數(shù)拿過來和函數(shù)列表中的參數(shù)對比。 在自己的函數(shù)列表中找不到就到父類的函數(shù)列表中去找,直到找到為止。
類方法
通過對象調(diào)用的方法,稱為對象方法,如init description等。
通過類對象調(diào)用的方法,稱為類方法,如alloc new等。
+ (instancetype)alloc + (instancetype)new
對象方法在聲明和定義時,以-開頭
類方法在聲明和定義時,以+開頭
在類方法中,self表示類對象,super表示父類對象
類方法在子類中也可以被重寫 ,類方法和對象方法可以重名
訪問類對象:
任意對象都可以通過class方法,獲得其類對象
- (Class)class
也可以通過類的class類方法,獲得其類對象
+ (Class)class
如:(c1和c2是同一類對象)
Person *p1 = [Person new]; Person *p2 = [Person new]; Class c1 = [p1 class]; Class c2 = [p2 class]; Person *p3 = [c1 new];
類對象的加載
在程序運行開始時,會加載一次項目中所有的類,類加載完畢就會調(diào)用類的load方法。
程序在第一次使用這個類時,會調(diào)用類的initialize方法。
這兩個方法是可以重寫的,都是類對象方法
+ (void)load + (void)initialize
注意:
使用第一次使用該類時,會先調(diào)用該類的父類的initialize方法
當有分類時,類和分類的load方法都會被調(diào)用;第一次使用該類時,只會調(diào)用分類的initialize方法。
類方法封裝對象的創(chuàng)建
當實例化一個對象時,需要編寫類似下面的代碼:
Person *p = [[Person alloc] initWithAge:20];
這樣的代碼比較啰嗦,可以添加一個類方法來簡化:
+ (instancetype) personWithAge:(int) age { return [[Person alloc] initWithAge:age]; }
這樣實例化對象的代碼為:
Person *p = [Person personWithAge:20];