OC基礎--構造方法 id類型,oc構造

來源:互聯網
上載者:User

OC基礎--構造方法 id類型,oc構造

new方法實現原理:

  new做了三件事情

       1.開闢儲存空間  + alloc 方法

       2.初始化所有的屬性(成員變數) - init 方法

       3.返回對象的地址

  [Person new]; == [[Person alloc] init];

    alloc: 1.開闢儲存空間 2.將所有的屬性設定為0 3.返回當前執行個體對象的地址

    init:  1.初始化成員變數, 但是預設情況下init的實現是什麼都沒有做 2.返回初始化後的執行個體對象地址

      注意: alloc返回的地址, 和init返回的地址是同一個地址

構造方法的概念及用途:

  在OC中init開頭的方法, 我們稱之為構造方法

  用於初始化一個對象, 讓某個對象一建立出來就擁有某些屬性和值

重寫init方法, 在init方法中初始化成員變數:

  重寫init方法必須按照蘋果規定的格式重寫, 如果不按照規定會引發一些未知的錯誤

    1.必須先初始化父類, 再初始化子類 

      子類繼承自父類  那麼子類擁有父類所有成員  子類必須調用父類的構造方法對這些成員進行初始化

    2.必須判斷父類是否初始化成功, 只有父類初始化成功才能繼續初始化子類

      為了防止父類的初始化方法release掉了self指向的空間並重新alloc了一塊空間。還有[super init]可能alloc失敗,這時就不再執行if中的語句

    3.返回當前對象的地址

      super 和 self 指向的是相同的訊息接收者 即誰調用就代表誰  

      - (instancetype)init      {          // 1.初始化父類 只要父類初始化成功 , 就會返回對應的地址, 如果初始化失敗, 就會返回nil  nil == 0 == 假 == 沒有初始化成功          self = [super init];          // 2.判斷父類是否初始化成功          if (self != nil) {                  // 3.初始化子類 設定屬性的值                  _age = 6;          }          // 4.返回地址          return self;      }

    簡版:

      - (instancetype)init      {          // 注意: 不要把 = 號寫為 ==     一定要將[super init]的傳回值賦值給self          if (self = [super init]) {              // 初始化子類              _age = 6;          }          return self;      }

自訂構造方法:

   自訂構造方法 其實就是自訂一個init方法:

     1.一定是對象方法

     2.一定返回id/instancetype

     3.方法名稱一定以init開頭

#import "Person.h"@implementation Person// 重寫init方法- (instancetype)init{    if (self = [super init]) {        self.name = @"王二小";        self.age = 12;    }    return self;}// 自訂構造方法  一個類可以有0個或者多個自訂構造方法- (instancetype)initWithName:(NSString *)name{    if (self = [super init]) {        _name = name;    }    return self;}// 自訂構造方法可以有1個或多個參數- (instancetype)initWithName:(NSString *) name andAge:(int) age{    if (self = [super init]) {        _name = name;        _age = age;    }    return self;}@end

自訂構造方法在繼承中得表現:

  誰聲明的成員就由誰去初始化(父類的屬性交給父類去處理  子類方法只處理自己專屬的屬性)

#import "Student.h" @implementation Student/*- (instancetype)initWithStudentNO:(NSString *)studentNO andName:(NSString *)name andAge:(int)age{    if (self = [super init]) {        self.name = name;        self.age = age;        self.studentNO = studentNO;    }    return self;} */- (instancetype)initWithStudentNO:(NSString *)studentNO andName:(NSString *)name andAge:(int)age{    // 由父類的構造方法去初始化 name 和 age 屬性    if (self = [super initWithName:name andAge:age]) {        _studentNO = studentNO;    }    return self;}@end

調用圖解:

   

自訂類Factory 方法:

   什麼是類Factory 方法:

     用於快速建立對象的類方法, 我們稱之為類Factory 方法

     類Factory 方法中主要用於 給對象分配儲存空間和初始化這Block Storage空間 

     自訂類Factory 方法是蘋果的一個規範, 一般情況下, 我們會給一個類提供自訂構造方法和自訂類Factory 方法用於建立一個對象

   規範:

     1.一定是類方法 +

     2.方法名稱以類的名稱開頭, 首字母小寫

     3.一定有傳回值, 傳回值是id/instancetype

    舉例: 

    [[NSString alloc] init];    [NSString string];       [[NSString alloc] initWithString:(NSString *)];    [NSString stringWithString:(NSString *)];     [[NSArray alloc] init];    [NSArray array];    [NSArray alloc] initWithObjects:(id), ..., nil];    [NSArray arrayWithObjects:(id), ..., nil];// 自訂類Factory 方法+ (instancetype)personWithName:(NSString *)name andAge:(int)age{    Person * person = [[Person alloc] init];    person.name = name;    person.age = age;    return person;}

自訂類Factory 方法在繼承中注意點:

  由於子類預設會繼承父類所有的方法和屬性, 所以類Factory 方法也會被繼承

  在類Factory 方法中建立對象一定不要使用類名來建立   一定要使用self來建立

    self在類方法中就代表類對象 (誰調用當前方法, self就代表誰)

    父類的類Factory 方法建立執行個體對象時是使用父類的類名建立的, 如果子類調用父類的類Factory 方法建立執行個體對象,建立出來的還是父類的執行個體對象

@interface Person : NSObject+ (id)person;@end @implementation Person+ (id)person{    return  [[Person alloc] init];}@end @interface Student : Person@property NSString *name;@end @implementation Student @end int main(int argc, const char * argv[]){    Student *stu = [Student person];// 等效於 [[Person alloc] init]  需要該為 [[self alloc] init]    [stu setName:@"lnj"]; // 報錯, 因為Person中沒有setName} // 自訂類Factory 方法  使用self 而不是 類名+ (instancetype)personWithName:(NSString *)name andAge:(int)age{    // Person * person = [[Person alloc] init];    Person * person = [[self alloc] init];    person.name = name;    person.age = age;    return person;}

id類型:

  id是一個資料類型, 並且是一個動態資料類型

       既然是資料類型, 所以就可以用來

         1.定義變數

         2.作為函數的參數

         3.作為函數的傳回值

  id == NSObject *   萬能指標

       id和NSObject *的區別: 

         NSObject *是一個待用資料類型

         id  是一個動態資料類型

  預設情況下所有的資料類型都是待用資料類型

     待用資料類型的特點: 

       在編譯時間就知道變數的類型, 

       知道變數中有哪些屬性和方法

       在編譯的時候就可以訪問這些屬性和方法, 

       如果是通過待用資料類型定義變數, 如果訪問不了屬於待用資料類型的屬性和方法, 那麼編譯器就會報錯    

     動態資料類型的特點:

       在編譯的時候編譯器並不知道變數的真實類型, 只有在啟動並執行時候才知道它的真實類型

       如果通過動態資料類型定義變數, 如果訪問了不屬於動態資料類型的屬性和方法, 編譯器不會報錯

  • 通過待用資料類型定義變數, 不能調用子類特有的方法
  • 通過動態資料類型定義變數, 可以調用子類特有的方法
  • 通過動態資料類型定義的變數, 可以調用私人方法
    • 弊端: 由於動態資料類型可以調用任意方法, 所以有可能調用到不屬於自己的方法, 而編譯時間又不會報錯, 所以可能導致運行時的錯誤
    • 應用情境: 多態, 可以減少代碼量, 避免調用子類特有的方法需要強制類型轉換
  • 為了避免動態資料類型引發的運行時的錯誤, 一般情況下如果使用動態資料類型定義一個變數, 在調用這個對象的方法之前會進行一次判斷, 判斷當前對象是否能夠調用這個方法
    • isKindOfClass     
        id obj = [Student new];            // isKindOfClass , 判斷指定的對象是否是某一個類, 或者是某一個類的子類        if ([obj isKindOfClass:[Student class]]) {            [obj eat];        }     
    • isMemberOfClass
        id obj = [Student new];        if ([obj isMemberOfClass:[Student class]]) {            // isMemberOfClass : 判斷指定的對象是否是當前指定的類的執行個體            [obj eat];        }   

instancetype和id的區別:

  instancetype == id == 萬能指標 == 指向一個對象

  id在編譯的時候不能判斷對象的真實類型

  instancetype在編譯的時候可以判斷對象的真實類型

    (一個在編譯時間不知道真實類型, 一個在編譯時間知道真實類型)

  id可以用來定義變數, 可以作為傳回值, 可以作為形參

  instancetype只能用於作為傳回值

    它會進行類型檢查,如果建立出來的對象,賦值了不相干的對象就會有一個警告資訊,防止出錯

  注意: 以後但凡自訂構造方法, 傳回值盡量使用instancetype, 不要使用id

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.