编写高质量OC代码52建议总结:1~8

来源:互联网 发布:美国黑色星期五 知乎 编辑:程序博客网 时间:2024/05/21 00:19
#pragma mark -- 1.了解OC的起源 /*  不说了。。。。  */#pragma mark -- 2.在类的头文件中尽量少引用其他类的头文件 /*  1.在编译一个类文件时,不需要知道类的全部细节,编译时,会引入很多用不到的细节,增加编译时间  2.除非有必要,请在.m文件中引入其他类的头文件,可以降低类之间的耦合  */#pragma mark -- 3.多用字面量语法,少用与其等价的方法//-(void)three{//    NSString *num = @"3";//    NSArray *array = @[@"3"];//    NSDictionary *dic = @{};//} /*  1. 字面量语法的局限性,除了字符串以外,所创建出来的对象必须属于Foundation框架  */#pragma mark -- 4.多用类型常量,少用#define预处理指令 /*  1.通过宏定义出来的常量没有类型信息  2.通过定义常量替代宏定义, static const int a = 1;  3.通过此方式定义的常量包含类型信息,清楚地描述了常量的含义。  4.全局常量  --.h文件  extern NSString *const name;  --.m文件  NSString *const name = @"";  5.在头文件中使用extern来声明全局常量  */#pragma mark -- 5.用枚举表示状态,选项,状态码 /*  1.枚举是一种常量的命名方式,每种状态都用一个便于理解的值表示,使代码更易懂。  --  enum state {    play,    stop  };  typedef enum state b;    -(void)state{    b a = play;  }    2.C++11标准修订了枚举的某些特性,可以指明用何种“底层数据类型”来保存枚举类型的变量。  --  enum state : NSInteger {    play,    stop  };    3.Foundation定义了一些辅助宏,也可以定义枚举  --普通枚举类型  typedef NS_ENUM(NSUInteger, a) {    b,    c  };    --选项枚举类型  typedef NS_OPTIONS(NSUInteger, cc) {    enumone         = 1 << 0,    enumtwo         = 1 << 1  };    4.要点:  --1.处理枚举switch语句时,不要实现default分支。这样,加入新枚举时,编译器会提示switch中有新枚举没有处理  --2.NS_ENUM,NS_OPTIONS定义枚举,并指明其底层数据类型,可以确保枚举是开发者所选的底层数据类型实现出来的,而不会采用编译器所选的类型。  */#pragma mark -- 6.属性//@dynamic 编译器不会自动为属性生成get,set方法 /*  属性  --原子性  ----nonatomic:不使用同步锁  ----atomic:编译器会通过其锁定机制确保原子性  ----备注:atomic性能开销较大。一个线程连续多次读取某个属性的同时,有别的线程同时改写该值,即使是atomic也会读到不同的值,如果为了线程安全,需要更深层的锁定机制。所以iOS开发中大部分属性都是nonatomic。    --读写权限  ----readwrite:可读可写,拥有get,set方法  ----readonly:可读不能写,拥有get方法,不创建set方法    --内存管理  ----assign:只针对纯量类型的简单赋值操作  ----strong:拥有关系,先保留新值,在释放旧值,然后将新值设置上去  ----week:非拥有关系,不保留新值,也不释放旧值,当属性所指的对象被摧毁,属性值被清空  ----unsafe_unretained:特质和assign相同,当属性所指的对象被摧毁,属性值不会被清空,不安全  ----copy:与strong类似,不保留新值,将其拷贝,保护其封装性,属性所指的对象是可变的,就应该用copy    --方法名  @property (nonatomic, assign, getter = ison, setter = onononon:) BOOL on;  -get方法变为  -(BOOL)isOn{    }    -set方法变为  -(void)onononon:(BOOL)on{    }    重新设置get,set方法名  ----getter = <name>:  ----setter = <name>:不常见      */#pragma mark -- 7.在对象内部尽量直接访问实例变量    /*     直接访问和通过属性访问的4点区别     1.直接访问,不经过“方法派发”,直接访问实例变量速度比较快,编译器所生成的代码会直接访问储存对象实例变量的那块内存。     2.直接访问实例变量,不会调用“设置方法”,绕过了为属性设置的“内存管理语义”,比如,ARC下直接访问一个声明为copy的属性,并不会拷贝该属性,只会保留新值并释放旧值。     3.直接访问实例变量不会触发键值观测(KVO)     4.通过属性访问有助于排查问题,“获取方法”,“设置方法”,监控该属性的调用者以及访问时机          ----------------------          写入实例变量的时候通过其“设置方法”,获取实例变量的时候直接访问     理由:提高读取速度,又能控制属性的写入操作,能够确保相关属性的“内存管理语义”得以贯彻。     注意:1.初始化时,如果属性在父类中定义,子类中无法直接访问,只能通过属性方法访问。其他情况建议直接访问。          2.用“懒加载”时,必须用“获取方法”读取实例变量。如果直接访问,将会看到没有设置好的属性。          */#pragma mark -- 8.理解“对象等同性”    /*     1、比较两个对象,“==”比较的是两个指针,而不是其所指的对象。     应该用“isEqual”判断两个对象的等同性,          2、NSObject类中有两个比较等同性方法     -----若两个对象相等,则其hash码一定相等。     -----若两个hash码相等,其对应的对象不一定相等     - (BOOL)isEqual:(id)object;     + (NSUInteger)hash;               3、-----  - (BOOL)isEqual:(id)object;  的实现机制     --1.首先判断两个指针是否相等,若相等则受测对象必定相等     --2.判断两个对象的类,如果类不相同,则两个对象必定不相等。(在继承体系中,父类可能等于子类)     --3.最后检查每个属性是否相等,都相等,则两个对象相等。          4、深度等同性判定:比较两个数组,先比较数组个数,然后每个元素比较“isEqual”,若都相等,则两个数组相等          5、容器中可变类的等同性:            -将两个相同的可变数组(NSMutableArray *A, NSMutableArray *B)放入set中,最后set只保留NSMutableArray *A,(因为两个数组相同)。            -将两个不同的数组(NSMutableArray *A, NSMutableArray *B)放入set中,set中有两个数组,然后改变NSMutableArray *B与NSMutableArray *A相等。此时set中会有两个相同的对象。会有隐患。          */

0 0
原创粉丝点击