编写高质量ios代码4

作者: ys_IT小学生 | 来源:发表于2016-08-12 09:33 被阅读97次

1. 以“类族模式”隐藏实现的细节

在我们平时的代码构建中,经常会用到继承。在类的继承关系以及方法的定义上有很多需要注意。
以下几点需要引起注意:

  • 在设计业务逻辑的时候,一定要考虑继承类的分层设计,将方法的实现和业务相对应,以降低类与类之间的耦合性。
  • 在系统的框架中有很多的类族,它们是类组中的抽象的基类。在使用该类族创建对象的时候会先分配一个继承自该类的子类,然后由该子类实例化想要的实力对象,举例说明;
id test = [[NSArray alloc]init];
if ([test class] == [NSArray class])
 {
            
 }

这段代码的if 判断条件永远也不会成立,因为[test class][NSArray class]的父类,下面用代码证明:

        MyArray * arr22 = (MyArray *)@[@1,@2,@3];
        MyArray1 * arr11 = (MyArray1 *)@[@1,@2];
        NSLog(@"%@",[arr22 class]);
        NSLog(@"%@",[arr11 class]);
        Father * father = [[Father alloc]init];
        Son * son = [[Son alloc]init];
        
        BOOL res = [father isKindOfClass:[NSObject class]];
        BOOL res1 = [father isKindOfClass:[Father class]];
        
        NSLog(@"res---%d",res);
        NSLog(@"res1---%d",res1);

        BOOL res2 = [son isKindOfClass:[NSObject class]];
        BOOL res3 = [son isKindOfClass:[Father class]];
        
        NSLog(@"res2---%d",res2);
        NSLog(@"res3---%d",res3);
        
        BOOL res4 = [father isMemberOfClass:[NSObject class]];
        BOOL res5 = [father isMemberOfClass:[Father class]];
        
        NSLog(@"res4---%d",res4);
        NSLog(@"res5---%d",res5);
        
        BOOL res6 = [son isMemberOfClass:[NSObject class]];
        BOOL res7 = [son isMemberOfClass:[Father class]];
        
        NSLog(@"res6---%d",res6);
        NSLog(@"res7---%d",res7);
        
        id temp = [[Son alloc]init];
        
        BOOL ress = ([Son class] == [temp class]);
        NSLog(@"%d",ress);
        
        id arr1 = [[NSArray alloc] init];
        BOOL ress1 = ([arr1 class] == [NSArray class]);
        NSLog(@"%d",ress1);
        
        NSLog(@"%@",[NSArray class]);
        NSLog(@"%@",[arr1 class]);
        
        BOOL ress2 = [arr1 isMemberOfClass:[NSArray class]];
        BOOL ress3 = [arr1 isKindOfClass:[NSArray class]];
        
        NSLog(@"%d",ress2);//0
        NSLog(@"%d",ress3);//1
        
        NSArray * arr2 = [[NSArray alloc]init];
        BOOL ress4 = ([arr2 class] == [NSArray class]);
        NSLog(@"%d",ress4);
        NSLog(@"%@",[arr2 class]);

打印结果:

打印结果

从打印结果我们可以清楚地看出,类之间的继承关系。

  • 我们在重写系统类的时候一定要注意查阅官方文档,看哪些方法是必须要实现的。例如当我们重写NSArray的时候,就必须要重写countobjectAtIndex:,重写其它系统类的时候也要注意查阅官方文档。

2.在类中只用关联对象存放自定义的数据

当我们在开发中遇到在某些类中,添加属性比较困难的时候,就可以使用关联对象。
关联对象是属于运行时机制里面的。
下面我们来看一下基本用法:

  • 设定关联对象
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

id object:当前对象
const void *key:所关联对象所对应的键
id value:要关联的对象
objc_AssociationPolicy policy:关联对象存储策略

  • 获取关联对象
id objc_getAssociatedObject(id object, const void *key)

id object:当前对象
const void *key:所关联对象所对应的键

  • 移除指定对象的全部关联对象
void objc_removeAssociatedObjects(id object)

下面看一段代码:

static void *key = @"xiao";
- (void)viewDidLoad {
    [super viewDidLoad];

    void (^block)(NSInteger) = ^(NSInteger num){
    
        NSLog(@"%ld",(long)num);
    };
    objc_setAssociatedObject(self, key, block, OBJC_ASSOCIATION_COPY);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self test1];
}

- (void)test1{

    void (^block)(NSInteger) = objc_getAssociatedObject(self, key);
    
    block(90);
}

这样我们就给当前的控制器添加了一个block属性,其实我们完全可以用属性去包装block,当我们无法给当前的抽象类添加属性的时候,我们其实就没有必要再创建该抽象类的实例,然后再去继承属性,这样会增加代码量,这样关联对象,可以节省代码量(在不方便创建属性的情况下),同时也可以优化代码结构。
注:使用这种方式其实也是有一定的弊端的,首先你关联的对象,内部银土其他参数的时候,比如引用block,很容易发生循环引用的现象,而我们又很难去发现,所以不是在不得已的情况下,尽量不要使用这种方式。

相关文章

网友评论

    本文标题:编写高质量ios代码4

    本文链接:https://www.haomeiwen.com/subject/puljsttx.html