Objective-C輕量級泛型__範型

來源:互聯網
上載者:User

在Apple發布Xcode7的時候,不僅把Swift程式設計語言升級到了2.0版本,而且還對Objective-C做了許多提升,包括引入__nonnull/__nullable。其中,對於Objective-C程式設計語言本身而言,更為有用的便是輕量級泛型。

其中,比較明顯的體現就是NSArray、NSDictionary這些容器類都採用了新引入的輕量級泛型。通過輕量級泛型,我們可以非常容易地擷取其中的元素,並訪問其相印特有的屬性和方法。我們舉一個簡單例子來闡明輕量級線程帶來的方便:



// 不帶泛型的情況 NSArray *numArray = @[@10, @20, @30]; int sum = [(NSNumber*)numArray[0] intValue] + [(NSNumber*)numArray[1] intValue] + [(NSNumber*)numArray[2] intValue];  

// 使用泛型的情況 NSArray<NSNumber*> *numArray = @[@10, @20, @30]; int sum = [numArray[0] intValue] + [numArray[1] intValue] + [numArray[2] intValue];

我們通過上述例子就能看到輕量級泛型帶來的文法上的便利性,即它是一塊甜美的文法糖(syntax sugar)。

之前Apple LLVM 6.0對C11標準的泛型——generic selection在Objective-C上支援得還不夠良好,但Apple LLVM 7.0上已經能完美支援了。比如下述例子:

int flag = _Generic(@100, NSNumber*:1, NSString*:2, int:3, default:0);    NSLog(@"The flag is: %d", flag);

 

上述代碼將成功地輸出“The flag is: 1”。

與C11的generic selection所不同的是,Objective-C內建的泛型其本質為covariant type,即協變類型。也就是,其泛型與Java的有些類似。它要求泛型必須是一個Objective-C類類型,即至少為id類型。對於上述NSArray的例子,我們在聲明一個Objective-C對象引用時,通過在類名後面添加<NSNumber*>來指明當前NSArray裡的元素都是NSNumber*類或其子類類型。這樣,我們在訪問其元素時可直接存取其intValue方法。

下面我們介紹如何自己定義一個泛型類。其文法描述如下:

@interface    class_name    <    __covariant    type_identifier    >    inherit_expression

這裡,class_name就是類名;type_identifier是類型標識符,該標識符可以由程式員自己命名;最後的inherit_expression表示繼承某個父類以及/或實現某些協議。

這裡引入了一個新的關鍵字——__covariant,表示後面的type_identifier是一個泛型型別。該泛型型別在聲明一個對象時進行具體指明。

下面舉一個具體的例子來說明如何具體使用Objective-C泛型。


@interface MyObject<__covariant T> : NSObject{@private        T obj;}

@property (nonatomic, retain) T obj;


@end@implementation MyObject@synthesize obj;- (void)dealloc{ if(obj != nil) [obj release]; NSLog(@"My object deallocated!"); [super dealloc];}@end@implementation ViewController- (void)viewDidLoad { MyObject<NSNumber*> *numObj = [[MyObject alloc] init]; numObj.obj = @100; [numObj release]; MyObject<NSString*> *strObj = [[MyObject alloc] init]; strObj.obj = @"Hello, world"; [strObj release];}

@end


上述代碼,我們定義了一個MyObject的泛型類,其泛型標識符用T表示。隨後,我們用該泛型T定義了一個私人對象obj,並用它作為一個property。

隨後,我們在viewDidLoad方法裡用MyObject<NSNumber*>聲明了一個對象numObj;用MyObject<NSString*>聲明了一個strObj對象。我們後面可以直接通過numObj.obj調用intValue來訪問其int值;直接通過strObj.obj來調用length方法以獲得其字串長度 // 不帶泛型的情況 NSArray *numArray = @[@ 10 , @ 20 , @ 30 ]; int sum = [(NSNumber*)numArray[ 0 ] intValue] + [(NSNumber*)numArray[ 1 ] intValue] + [(NSNumber*)numArray[ 2 ] intValue]; // 使用泛型的情況 NSArray<NSNumber*> *numArray = @[@ 10 , @ 20 , @ 30 ]; int sum = [numArray[ 0 ] intValue] + [numArray[ 1 ] intValue] + [numArray[ 2 ] intValue];

相關文章

聯繫我們

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