#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中会有两个相同的对象。会有隐患。 */
新闻热点
疑难解答