#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中会有两个相同的对象。会有隐患。
*/
编写高质量OC代码52建议总结:1~8
最新推荐文章于 2017-07-27 10:01:49 发布