第3章 接口与API设计
第15条:用前缀避免命名空间冲突
1.OC没有命名空间机制;
2.避免此问题的唯一方法是:为所有名称都加上适当前缀;
3.Apple宣称其保留使用所有“两字母前缀”的权利,所以你自己选用的前缀应该是三个字母;
4.不仅是类名,应用程序中的所有名称都应加前缀(包括纯C函数和全局变量)。
第16条:提供“全能初始化方法”
1.如果一个类有多个初始化方法,应该选定一个作为全能初始化方法,令其他初始化方法都调用它;
2.如果子类的全能初始化方法与超类方法的名称不同,那么总应覆写超类的全能初始化方法;
3.有时候可能需要编写多个全能初始化方法;
4.每个子类的全能初始化方法都应该调用其超类的对应方法,并逐层向上。
第17条:实现description方法
1.description方法定义在NSObject协议里,默认只是输出类名和对象的内存地址;
2.可以覆写description方法并将描述此对象的字符串返回即可;
3.其他一些细节详见第70页…
第18条:尽量使用不可变对象
1.应该尽量把对外公布出来的属性设为只读,而且只在确有必要时才将属性对外公布;
2.虽然有些属性没有设置方法(setter),但还是应该在文档里知名实现所用的内存管理语义;
3.有时可能想修改封装在对象内部的数据,但是却不想令这些数据为外人所改动。这种情况下,通常做法是在对象内部将readonly属性重新声明为readwrite;
4.当然在3所说的,可能会产生“竞态条件”,必要时通过“派发队列”(第41条),将所有数据存取操作设为同步操作;
5.通过KVC等“杂技代码”绕过本类所提供的API,只能说让他们后果自负了;
6.不要在返回的对象上查询类型以确定其是否可变(详见书77页)。
第19条:使用清晰而协调的命名方式
1.各种命名规则详见书本…
第20条:为私有方法名加前缀
1.OC语言没办法将方法标为私有。每个对象都可以响应任意消息,而且可在运行期检视某个对象所能直接响应的消息;
2.根据给定的消息查出其对应的方法,这一工作要在运行期才能完成,所以OC没有那种约束方法调用的机制用以限定谁能调用此方法,能在哪个对象上调用此方法以及何时能调用此方法;
3.苹果公司喜欢单用一个下划线作为私有方法的前缀,因此你不应该单用一个下划线做前缀,以免在子类里可能无意间覆写父类的同名方法。
第21条:理解Objective-C错误模型
1.OC语言对异常采用的办法是:只在极其罕见的情况下抛出异常,异常抛出之后,无须考虑恢复问题,而且应用程序此时也应该退出;
2.OC没有办法将某个类标识为“抽象类”,要想达成类似效果,最好的办法是在那些子类必须覆写的超类方法里抛出异常;
3.对于“不那么严重的错误”,OC的编程范式是:令方法返回nil/0,或者使用NSError;
4.例子可看书第88页…
第22条:理解NSCopying协议
1.如果想令自己的类支持拷贝操作,就要实现NSCopying协议,该协议只有一个方法:copyWithZone;
2.copy方法由NSObject实现,该方法只是以“默认区”为参数来调用“copyWithZone:”;
3.无论当前实例是否可变,若需获取其可变版本的拷贝,均应调用mutableCopy方法;若需要不可变的拷贝,则总应通过copy方法来获取;
4.“深拷贝”和“浅拷贝”的问题,见第92页。
第4章 协议与分类
第23条:通过委托与数据源协议进行对象间通信
1.“委托模式”:定义一套接口,某对象若想接受另一个对象的委托,则需遵从此接口,以便成为其“委托对象”;
2.假如声明属性的时候用strong将本对象与委托对象之间定为“拥有关系”,那么就会引入“保留环”(retain cycle);
3.实现委托对象的办法是声明某个类遵从委托协议,然后把协议中想实现的那些方法在类里实现出来。某个类若要遵从委托协议,可以在其接口中声明,也可以在“class-continuation分类”中声明;
4.委托协议中的方法一般都是“可选的”,如果在委托对象上调用可选方法,那么必须提前使用类型信息查询方法;
5.可以把委托对象能否响应某个协议方法这一信息缓存起来,以优化程序效率;
第24条:将类的实现代码分散到便于管理的数个分类之中
1.详见101页…
第25条:总是为第三方类的分类名称加前缀
1.分类中的方法是直接添加在类里面的,它们就好比这个类中的固有方法。将分类方法加入类中这一操作是在运行期系统加载分类时完成的,运行期系统会把分类中所实现的每个方法都加入类的方法列表中;
2.如果类中本来就有此方法,而分类中又实现了一次,那么分类中的方法会覆盖原来那一份实现代码;
3.多次覆盖的结果以最后一个分类为准;
4.即便加了前缀,也难保其他分类不会覆盖你所写的方法,然而几率却小了很多,因为其他程序库很少会和你选用同一个前缀;
第26条:勿在分类中声明属性
1.尽管从技术上说,分类里也可以声明属性,但还是要尽量避免,因为,除了“class-continuation分类”外,其他分类都无法向类中新增实例变量,因此,它们无法把实现属性所需的实例变量合成出来;
2.关联对象能够解决分类不能合成实例变量的问题,但还是不要做为好啊…
第27条:使用“class-continuation分类”隐藏实现细节
1.对于那些不需要对外公布但却应该具有的方法及实例变量,应该使用“class-continuation分类”;
2.讨论了一个OC和C++混合的问题,可以看看….
第28条:通过协议提供匿名对象
1.暂时先不管吧…
第5章 内存管理
第29条:理解引用计数
1.从OS X 10.8开始,“垃圾收集器”已正式废弃,而iOS从未支持过垃圾收集;
2.每个应用程序都有一张“对象图”,在Mac OS X中,根对象是NSApplication对象,在iOS中,则是UIApplication对象,两者都是应用程序启动时创建的单例;
3.在alloc或“init”方法返回后,其保留计数至少为1(也有可能大于1);
4.因过早释放对象而导致的bug很难调试,因为它不一定马上崩溃,一般调用完release后记得清空指针;
5.在setXXX方法中,retain和release的顺序很重要(不过在ARC下已经没什么卵用);
6.自动释放池的使用…见第120页;
7.“保留环”,在垃圾收集环境中,通常将其认定为“孤岛”,垃圾收集器会将其全部收走,但在OC的引用计数架构中,则享受不到这一便利,通常采用“弱引用”来解决此问题。
第30条:以ARC简化引用计数
1.使用ARC时一定要记住,引用计数实际上还是要执行的,只不过保留与释放操作现在是由ARC自动为你添加;
2.由于ARC会自动执行retain、release、autorelease等操作,所以直接在ARC下调用这些内存管理方法是非法的(dealloc也不能调用);
3.直接调用上述任何方法都会产生编译错误,此时必须信赖ARC;
4.ARC在调用这些方法时,并不通过普通的OC消息派发机制,而是直接调用其底层C语言版本,这样性能更好;
5.若方法名以下列词语开头,则其返回的对象归调用者所有:alloc、new、copy、mutableCopy;
6.归调用者所有的意思是:调用上诉四种方法的那段代码要负责释放方法所返回的对象;
7.如果还有其他对象保留此对象,并对其调用了autorelease,那么保留计数的值可能比1大,这也是retainCount方法不太有用的原因之一;
8.若方法名不以上述四个词开头,则表示其所返回的对象并不归调用者所有,在这种情况下,返回的对象会自动释放,所有其值在跨越方法调用边界后依然有效;
9.维系这些规则所需的全部内存管理事宜均由ARC自动处理,其中包括在将要返回的对象上调用autorelease;
10.