iOS學習筆記(01) - 泛型

來源:互聯網
上載者:User

標籤:

  決定新開一坑,在不斷學習的同時分享自己的學習曆程給大家,既是對自己學習的記錄,又希望能對大家提供些微的協助。

  

  這一篇文章主要來介紹泛型的意義、使用與聲明方法等。

1.泛型:限制類型

  1.1.泛型使用情境:

    1.在集合(數組NSArray、字典NSDictionary、集合NSSet)中使用泛型比較常見。

    2.當聲明一個類,但是類裡面的某些屬性的類型不確定的時候,我們才使用泛型。

  1.2.泛型書寫規範

    在類型後面定義泛型:NSMutableArray<UITouch *> dataArray

  1.3.泛型修飾

    只能修飾方法的調用。

  1.4.泛型好處:

    1.提高開發的規範,減少程式員之間的交流。

    2.通過集合取出來的對象,可以直接當做泛型對象使用。這樣我們就可以直接使用.點文法。

  

2.代碼使用泛型:

  2.1.聲明一個泛型為NSString的數組

1 // 具體做法就是在 NSMutableArray 後帶一個 <NSString *> ,角括弧內部即為泛型型別
2 @property (nonatomic, strong, nullable) NSMutableArray<NSString *> *dataArray;

  2.2.當我們要給數組添加對象或取出對象的時候,系統就會自動提示應該傳入或者取出來的對象的類型,這個類型就是你剛才聲明的泛型型別

 1     // 1.沒有使用泛型 2 //    [self.dataArray addObject:<#(nonnull id)#>]; 3  4     // 2.使用泛型 5 //    [self.dataArray addObject:<#(nonnull NSString *)#>]; 6      7     // 3.添加不正確的類型,會出現警告 8 //    [self.dataArray addObject:@1]; 9     10     // 4.我們可以直接將集合中取出來的對象當做泛型使用11     NSInteger length = [self.dataArray.firstObject length];

  

  基本上實現了使用泛型過程中可能出現的情況。

 

3.泛型的自訂

  剛才我們只是實現了系統類別NSMutableArray的泛型。接下來我們要考慮下,我們怎麼樣在我們自己的類中聲明一個泛型的屬性呢?

  為了這個目的,我們建立一個 Language 的類表示 “語言”。並且建立兩個 Language 的子類,分別叫 Java 和 IOS 。很明顯這兩個是“某一個類型的語言”。我們建立一個Person的類,給類聲明一個泛型,在類的 .h 檔案中聲明一個聲明一個屬性,這個屬性工作表示這個人會的語言,即為 IOS 或者 Java 。那麼我們有以下兩種聲明方式:  

1 // 語言2 // 1.id:任何對象都能傳進來3 //@property (nonatomic, strong, null_unspecified) id language;4 // 2.Language:在外面調用的時候不能提示具體是哪種語言5 //@property (nonatomic, strong, null_unspecified) Language *language;

  因為 Language 這個語言並不能代表這個 Person 究竟會什麼語言,我們需要的屬性時 IOS 和 Java。這兩種都可以在調用的時候傳入 Java 和 IOS 兩種對象,但它們的缺點也非常明顯,若使用 id 則我們可以傳入任何對象,而不只是 Java 和 IOS ;使用 Language * 呢,我們沒有辦法在編譯的時候確定這個人究竟會什麼語言,而只能在運行時判斷。有沒有辦法讓我們在編譯的時候就能知道 Person 具體會哪種 Language 呢?

  辦法就是泛型。

  聲明自訂類的泛型,我們需要做這樣一步:

1 // (給類)聲明一個泛型2 @interface JTPerson<ObjectType> : NSObject

  看出區別了嗎?我們在 interface 類名之後加了一對角括弧 <> ,中間是 ObjectType 。這個就代表泛型。這樣我們在聲明屬性的時候就可以這麼寫: 

1 @property (nonatomic, strong, null_unspecified) ObjectType language;

  也就是,我們現在不指定具體的類型,而在執行個體化這個類的時候確定這個泛型。若不確定,那麼所有的 ObjectType 會自動變成 id 。像這樣:

 1     // iOS 2     JTPerson<IOS *> *iOSP = [[JTPerson alloc] init]; 3       4 //    [iOSP setLanguage:@"123"]; 5      6 //    [iOSP setLanguage:<#(IOS * _Null_unspecified)#>]; 7      8 //    [iOSP setLanguage:[[Java alloc] init]]; 9     10     // Java11     JTPerson<Java *> *javaP = [[JTPerson alloc] init];12     13 //    [javaP setLanguage:@"123"];14     15 //    [javaP setLanguage:<#(Java * _Null_unspecified)#>];16     17 //    [javaP setLanguage:[[IOS alloc] init]];

  這樣,我們在聲明 Person這個類的時候,就順便聲明了這個類的泛型。這樣系統就會在你使用到泛型的屬性與方法的時候,自動提醒你聲明的泛型型別了。

 

4.泛型的協變與逆變

  首先我們來看一個方法:

1 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {2     3     [touches anyObject];4 }

  大家應該很熟悉這個方法了。這就是 UIViewController 繼承自 UIResponder 的方法,是點擊這個視圖控制器之後事件鏈的最後一環。這時候經過上面的學習,我們會看到這其中就使用了泛型: (NSSet<UITouch *> *) 。這樣我們點進集合 NSSet 會發現它是這樣寫的:

  前後我們都很清楚: interface:聲明;NSSet:集合;ObjectType:泛型;NSObject:是NSSet的父類,也是根類;後面角括弧中表示的是遵守的協議。

  那麼 __covariant 代表什嗎?

  這裡我們先來學習兩個單詞: covariant:協變的 contravariant:逆變的。

  那麼 __covariant協變 代表什嗎?

 

  我們來試一下。在剛才的自訂類 Person 的泛型 ObjectType 前加這樣一條修飾: __covariant

1 @interface JTPerson<__covariant ObjectType> : NSObject

  然後在調用的時候,我們聲明兩個執行個體,泛型分別為父類 Language 和子類 IOS。這樣若泛型為 IOS 的 Person 想給泛型為 Language 的 Person 賦值,會怎麼樣:

1     // 1.協變2     // iOS3     JTPerson<IOS *> *iOSP = [[JTPerson alloc] init];4     5     // Language6     JTPerson<Language *> *p = [[JTPerson alloc] init];7     8     // 如果子類想給父類賦值,協變9     p = iOSP;

  並沒有報錯。

  也就是說,若泛型為子類的對象想給泛型為父類的對象賦值的時候,我們需要在泛型前面添加 協變__convariant ,告訴編譯器,這樣轉換沒有問題。

  同理,__contravariant逆變就是若泛型為父類的對象想給泛型為子類的對象賦值的時候,我們需要在泛型前面添加 逆變__contravariant ,告訴編譯器,這樣轉換沒有問題。

  這就是協變與逆變的含義。

  協變與逆變本身是物件導向繼承的語言的一個特性,也並不只應用在泛型這裡。

iOS學習筆記(01) - 泛型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.