美文网首页
Effective Objective - C 2.0 笔记

Effective Objective - C 2.0 笔记

作者: 王小明if | 来源:发表于2014-02-13 15:25 被阅读722次

    Objective-C 入门

    1. Object-C 是 C 的超集,它使用运行时来进行动态绑定,所有对象的类型都是在运行时才能确定的,都是以消息传递的机制运作;所有对象都是在heap中allocated的,在stack中allocate对象是不合法的;内存管理在objc中被抽象为以引用计数的方式来进行管理。

    2. 最小化在头文件中import的头文件数量,在尽可能的深处引用它;使用提前声明,消除多余的引用,消除互相引用;使用 continuation category 细化类别 来减少 多余的类方法造成的 过多编译量。

    • 对于NSArray、NSNumber、NSDictionary的快捷初始化方法,使用literals语法,使代码更加简洁,更加安全,但只能创建immutable的对象,对于mutable的对象需要使用mutableCopy

       NSMutableArray *mutable = [@[@1,@2,@3,@4,@5] mutableCopy]; 
      
    1. 选择使用

      static const NSIntger durantion = 1;  
      

      来代替

      #define durantion 1 
      

      定义常量,优点在于避免重定义造成的错误、加入global symbol Table能多处使用、更加严格的类型定义

    对象,消息与运行机制

    1. 最好用直接访问的方法来读取成员变量,而用property生成的setter方法来赋值成员变量;
      直接赋值更加快速,但会失去了对成员变量制定的property属性的内存控制;并且不会触发对于该成员变量 KVO 监听函数;
      初始化函数中,最好对成员变量直接赋值,因为可能在子类中重载的setter方法会做出特殊的过滤处理;当然,如果该成 员变量只声明在此类的父类中,那只能调用setter方法;
      如果成员变量是使用lazy initialization 方法,如

       - (IFObject*)object  
       {  
           if(!_object)  
           {  
               _object = [IFObject new];  
           }  
           return _object;     
       }  
      

      那读取它时需要调用它的getter方法,否则会出错。

    2. 使用动态绑定对象,使代码更优雅

      void (^block)(NSInteger) = objc_getAssociatedObject(alertView, kAlertKey);  
      

      用Key获取与该对象关联的对象或block
      可以视为Key/Value方式的扩展,需要 #import <objc/runtime.h>
      在AlertView中,我们可以在声明每个AlertView后将处理其点击的delegate方法写为block,与该alertView绑定,这样能 够避免同个类文件声明多个AlertView后委托方法的臃肿不堪
      同理,可应用在多个场景中。

    3. 了解Objective-C的msgSend机制及函数混淆机制;

    4. 使用[object isKindOfClass:]检查是否为该类或其子类,使用[object isMemberOfClass:]检查是否为该类;

    对象接口设计

    1. 在命名类时,多使用三字母前缀(避免与系统二字母前缀冲突)避免命名空间冲突;
      引入第三方库时,修改库命名,加入自定义的前缀,以防多次引入第三方库导致的命名空间冲突。
    2. 一个类必须只有一个指定的初始化方法,其他初始化方法都最终指向它;
      在子类中只需要重载指定初始化方法即可;
    3. 定义类的description方法,返回描述对象的NSString,使对象能被NSLog输出;
      若需要,定义类的dubugDescription方法,提供更加详细的描述方法;
    4. 偏向immutable对象,防止mutable对象在运行时的修改导致程序异常;
      尽可能类头文件只暴露具有readonly属性的property,若在类内部需要修改该成员变量,可使用直接访问,或在class-continuation catalogy里将该property的属性定义为readwrite;
      提供一个修改类成员变量的公共方法,而不是将一个可变的成员变量暴露在头文件中;
    5. 在类接口命名上按照Objc的标准进行命名,在命名上表意清晰并完整,向句子一样表述接口作用;
    6. 在Objc中,没有一个能将类中成员或方法定义为private的方法,偏向用p_前缀修饰private变量与方法,以便于公共方法区分开来;
    7. 若是程序发生致命错误,用NSException来抛出异常终止程序,在非致命错误上,返回nil或者0,或者返回一个NSError对象通过委托方法等方式对错误进行处理;

    委托与协议

    1. 使用delegate委托模型进行对象间的消息传递,优化点为可以使用缓存机制来保存委托对象的消息响应状况(之后再写文章详细描述);

    2. 使用categories扩展类别技术分割类文件,实现类方法功能的分类,防止单一类文件代码过于冗长;也可以创建一个private的类别,表示类的私有方法;

    3. 当自定义或引入categories时,尽可能加上自定义的前缀,以免与系统类别定义冲突;

    4. 无法在categories类别(除continuation categories)添加property,在添加的类别中,property成员变量是无法进行synthesized,因此无法为property提供gettersetter方法;解决方法只有自定义property的访问与修改方法,并加上

      @dynamic property
      

      来表明property的的访问与修改方法在运行时生成;

    5. 在类的实现文件中使用class-continuation categories技术

      @interface WYObject()
      //Property and method
      @end
      

      这个类别可用于

      • 可以添加成员变量方法到类中,因此可以隐藏无需公开在头文件的成员变量;
      • 可以重新声明头文件中声明的property,修改其属性,如将readonly改为readwrite
      • 声明类的私有函数(可以不在类别中声明,但这能增加可读性);
      • 能够在类别中声明类遵守的protocols协议,若该类不希望公开;
    6. 使用protocol协议来提供一个匿名类

      @property (nonatomic,weak) id<WYDelegate> delegate
      

      当一个对象的类型需要被隐藏,或者对象实现了什么方法比对象类型更重要时,可以采用匿名类。

    内存管理

    尽管现在已经是ARC的年代了,但是ARC的本质是系统在程序的适当地方添加上内存管理代码,因此对于内存管理的技术还是需要了解清楚地。

    1. 程序中,所有对象通过引用关系组成一张内存计数的对象图,在一个对象的声明周期中,对其的retain与release次数必须相等;
    2. 使用@autureleasepool内存池,加在大量动态内存生成的代码中,使内存池立即释放内存,防止内存高峰导致程序crash;
    3. 禁止使用retainCount方法,因为在程序的某一刻,retainCount返回的数值是不能确定的。

    相关文章

      网友评论

          本文标题:Effective Objective - C 2.0 笔记

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