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