刚刚升级后,发现输入提示等有所变化,上网看下,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