[X-Code7新功能之一]OC的泛型支援
阿新 • • 發佈:2019-02-20
剛剛升級後,發現輸入提示等有所變化,上網看下,oc開始支援泛型了,這個絕對是好事啊。
說明oc還沒有被淘汰,蘋果還在繼續完善,希望能越來越好吧(肯定能,不差錢兒麼~)
#import <UIKit/UIKit.h> @interface MyBase : NSObject -(NSString*)description; @end @interface MyChild : MyBase -(NSString*)description; @end /*MyTemplate<ObjectType: NSNumber*>這樣寫好使,能定義類型範圍*/ @interface MyTemplate<__contravariant ObjectType> : NSObject { @private /*目前在類裡面只有nsarray,nsset,nsdictionary可以識別~*/ NSMutableDictionary<ObjectType,NSString*>* _Dic; } -(ObjectType)GetFirstObj; /*函式的宣告可以用模版型別,但實現就不能用了,只能用id替代~*/ -(void) setValue:(ObjectType)value forKey:(NSString *)key; @end @interface ViewController : UIViewController @end
#import "ViewController.h" #import <UIKit/UIKit.h> @implementation MyTemplate -(instancetype) init { if (self = [super init]) { _Dic = [[NSMutableDictionary<ObjectType,NSString*> alloc] initWithCapacity:3]; } return self; } -(void) setValue:(id)value forKey:(NSString *)key { [_Dic setValue:value forKey:key]; } -(id)GetFirstObj { if (_Dic.count == 0) { return nil; } NSEnumerator* ValueEnumer = [_Dic objectEnumerator]; return [ValueEnumer allObjects].firstObject; } @end @implementation MyBase -(NSString*)description { return @"MyBase"; } @end @implementation MyChild -(NSString*)description { return [NSString stringWithFormat:@"MyChild,Super %@", [super description]]; } @end @interface ViewController () @end @implementation ViewController { NSMutableArray<NSString*>* _ArrGenericity; NSMutableArray<MyBase*>* _ArrBase; } - (void)viewDidLoad { [super viewDidLoad]; _ArrGenericity = [[NSMutableArray<NSString*> alloc] initWithCapacity:3]; NSString* str = @"Hello"; /*只能用nstring*型別的了,變數、常量都可以*/ [_ArrGenericity insertObject:str atIndex:0]; [_ArrGenericity insertObject:@"World" atIndex:1]; [_ArrGenericity enumerateObjectsUsingBlock: ^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSLog(@"%@",obj); }]; /*這個地方有寫不妥,不是很嚴格,只要是NSArray都可以~*/ if ([_ArrGenericity isKindOfClass:[NSMutableArray<NSDictionary*> class]]) { NSLog(@"Kind Class is %@",[NSMutableArray<NSString*> class]); } /*不管什麼型別都不好使,看來只能用isKindOfClass判斷了,再試驗自定義*/ if ([_ArrGenericity isMemberOfClass:[NSArray<NSString*> class]]) { NSLog(@"Member Class is %@",[NSArray<NSString*> class]); } _ArrBase = [[NSMutableArray<MyBase*> alloc] initWithCapacity:3]; MyChild* C1 = [[MyChild alloc] init]; [_ArrBase insertObject:C1 atIndex:0]; [_ArrBase enumerateObjectsUsingBlock: ^(MyBase * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSLog(@"%@",obj); }]; /*通過型別的輸出和isKindOfClass可以看出,對型別的檢查沒有增加元素型別*/ if ([_ArrBase isKindOfClass:[NSMutableArray<MyChild*> class]]) { NSLog(@"%@",[NSMutableArray<MyBase*> class]); } /*物件聲明後,裡面的成員方法的構造型別自動被替換,這點很爽~,但裡class依然沒有加入型別判斷*/ MyTemplate<NSString*>* m = [[MyTemplate<NSString*> alloc] init]; [m setValue:@"World"forKey:@"hello"]; NSLog(@"Class is %@, first Value is %@",[m class],[m GetFirstObj]); /*加不加__covariant關鍵字都有協變效果*/ MyTemplate<MyBase*>* m1 = [[MyTemplate<MyBase*> alloc] init]; MyChild* C2 = [[MyChild alloc] init]; [m1 setValue:C2 forKey:@"c2"]; NSLog(@"Class is %@, first Value is %@",[m1 class],[m1 GetFirstObj]); /*加__contravariant也有警告,不清楚原因啊~*/ MyTemplate<MyChild*>* m2 = [[MyTemplate<MyChild*> alloc] init]; MyBase* C3 = [[MyBase alloc] init]; [m2 setValue:C3 forKey:@"c2"]; NSLog(@"Class is %@, first Value is %@",[m2 class],[m2 GetFirstObj]); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
總結下吧:
1,沒有像c++那樣,在類宣告的地方能定義個模版型別,然後整個類到處都能用,包括實現部分。也許很快能這樣了。
2,檢查型別的時候也沒有帶出模版的具體類,不是很嚴格~
參考:http://blog.csdn.net/leikezhu1981/article/details/47418011