OC基础学习-05

72 阅读5分钟

Category

  • OC特有的语法
  • 作用:
    • 可以在不修改原来类的基础上,为这个类扩充一些方法
    • 一个庞大的类可以分模块开发
    • 一个庞大的类可以由多个人来编写,更利于团队合作
  • 分类的定义
@interface 类名 (分类名称)

//不允许添加变量,只能添加新方法
@end
  • 分类的实现
@implementation 类名 (分类名)
//新方法的实现
@end
  • 分类的注意点
    • 只能添加方法,不是添加属性
    • 分类中的property,只会生成getter/setter的声明,不会实现及私有的成员变量
    • 可以在分类中访问原有类中.h的属性
    • 原有类和分类中同名的方法,会调用分类中的方法,忽略原有类方法,开发中尽量避免
    • 如果多个分类中都有和原有类中同门的方法,那么调用该方法是由编译器决定的,会调用编译器最后加载的同名方法
  • 方法的调用顺序:分类->本类->父类
  • 匿名分类/类拓展
    • 延展类别又称为扩展,是分类的一个特例
    • 可以为某个类扩展一些私有的成员变量和方法
      • 写在.m文件中
    • 格式
    @interface 类名 ()
    {
    }
    @end
    

Block

  • IOS 中一种特殊的数据类型,所以可以作为形参,返回值等
  • 定义
    返回值类型 (^block变量名)(形参列表 )= ^(形参列表){
    
    }
    
  • 如果block没有参数,(形参列表)可以省略
  • 利用typedef给block起别名,和指向函数的指针一样,block变量的名称就是别名
  • 当发现代码的前面后面都是一样的时候,这个时候就可以使用block
  • 使用注意
    • block 中可以访问外面的变量
    • block中可以定义和外界同名的变量,并且如果在block中定义了和外界同名的变量,在不block中访问的就是block中的变量
    • 默认情况下,不可以在block中修改外界变量的值,因为block中的变量和外界变量并不是同一个变量,如果block中访问到了外界的变量,block会将外界的变量拷贝一份到堆内存中
    • 因为block中使用外界变量是copy的,所以外界修改并不会影响里面的
    • 如果想在block中修改外界变量的值,必须在外部变量前面加上——block,此时可以影响外部的值,没有加——block是值传递,加了之后是地址传递
    • block可以存储在堆中,也可以存储在栈中,默认存储在栈中,如果堆block进行一个从copy操作(Block_copy(myBlock) ,这样block就在堆中了),block会转移到堆中;如果block在栈中,block中访问了外界的对象,那么不会对对象进行retain操作,但是如果block存储在堆中,block中访问了外界对象,那么会对外界的对象进行一次retain
    • 如果在block中访问了外界的对象,一定要给对象加上——block,只要加上了_block,哪怕block在堆中,也不要会对外界的对象进行retain

Protocol

  • Java中有接口interface这个概念,接口就是一堆方法的声明没有实现,而在OC里面interface是一个类的头文件的声明,并不是真正意义上的接口的意思,OC中的接口是由protocol来实现的
  • 定义
@protocal 协议名称
//方法声明列表
@end
  • protocol和继承的区别
    • 继承之后默认就有实现,而protocol只有声明没有实现
    • 相同类型的类可以使用继承,但是不同类型的类只能使用protocol
    • protocol可以用于存储方法的声明,可以将多个类中共同的方法抽取出来,以后让这些类遵守协议即可
  • protocol注意
    • 协议只能声明方法,不能声明属性
    • 父类遵循类某个协议,子类也会自动遵循这个协议
    • 在OC中一个类可以遵守多个协议,但是OC中的类只能继承一个父类
    • 协议可以遵守其他协议,只要一个协议遵守了其他协议,那么这个协议就会自动包含其他协议的声明
    • @required 必须实现,@optional 可选实现,默认是required的,但是只是建议,不实现也只是警告不会报错
  • protocol应用
    • 类型限定
    //将协议写在数据类型的右边,明确的标注如果想给该变量赋值,那么该对象必须遵守某个协议
    Wife<WifeCondition> *w = [Wife new];
    //类型限定是写在数据类型的右边
    @property (nonatomic,strong) Wife<WifeCondition> *wife;
    
    @interface Wife:NSObject<WifeCondition>
    @end
    
    //虽然在接受某一个对象的时候,对这个对象进行了类型限定(限定他必须实现某个协议),但是并不意味着这个对象就真正的实现了该方法,所以在每次调用对象的协议方法时应进行一次验证
    if([self.wife respondsToSelector@selector(cooking)]){
        [self.wife cooking];
    }
    
    • 代理设计模式
      • 心相印和超市,超市就是心相印的代理,她可以帮助心相印卖纸巾,也就是说,代理也帮助另一个类做一些事情,
      • 当A对象想监听B对象的一些变化时,可以使用代理模式
      • 当B对象发生一些事情,想通知A对象的时候,可以使用代理模式
      • 当A对象无法进行某些行为的时候,想让对象B帮忙处理