【Effective Objective-C 2.0读书笔记】第三章:接口和API设计

一旦你完成了一个应用,你可能会希望在以后的工程中重用部分代码。你也可能会发布一些代码以供其他人来使用。这意味着你需要使用Objective-C语言常用的编程范式(paradigm),同时也需要了解各种可能遇到的陷阱。

第15条:用前缀避免命名空间冲突

Objective-C中没有C++等语言中那种内置的命名空间机制。避免类名和方法名冲突的方法是使用前缀。所选前缀可以是公司名称、应用程序或者二者结合而来的简称。但需要注意的是,使用Cocoa创建应用程序时,Apple已宣称保留使用所有“两字母前缀”的权利,所以你自己所选用的前缀应该是三个字母的。

如自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀。

第16条:提供”全能初始化方法”(Designated Initializer)

全能初始化方法:可为对象提供必要信息,以便其能完成工作的初始化方法。若类的初始化方法有多个,选定一个作为全能初始化方法,令其他初始化方法都来调用它。

类继承时需要注意一个重要问题:若子类的全能初始化方法与超类的全能初始化方法名称不同,那么总应覆写超类的全能初始化方法。如果超类的初始化方法并不适用于子类,那么就应覆写这个超类方法,并在其中抛出异常。

第17条:实现description方法

调试程序时,需要打印并查看对象信息。在构建需要打印到日志的字符串时,对象会收到description消息,该方法返回的描述信息将取代“格式字符串”(format string)中的“%@”。默认会输出类似“”这样的信息,如果想要输出更为有用的信息就要覆写description方法。例如:

- (NSString*)description {
    return [NSString stringWithFormat:@"<%@: %p, \"%@ %@\">",
            [self class], self, _firstName, _lastName];
}

或者借用NSDictionary类的description方法,例如:

- (NSString*)description {
return [NSString stringWithFormat:@"<%@: %p, %@>",
    [self class],
    self,
    @{@"title":_title,
    @"latitude":@(_latitude),
    @"longitude":@(_longitude)}
    ];
}

你可能不想将类名和对象指针地址这种额外信息放在普通的描述信息里,而只想将其用于调试。这时就可以覆写debugDescription,将额外信息放到这个方法中返回。此方法在调试器中以控制台命令打印对象(例如po命令)时才会调用。

第18条:尽量使用不可变对象

在编程实践中,应该尽量将对外公布的属性设置为只读,而在确有必要时才将属性对外公布。

若某属性仅可于对象内部修改,则在“class-continuation分类”中将其由readonly属性扩展为readwrite属性。尽管将属性设置为只读之后,在对象外部仍然可以通过“键值编码”(KVO)技术,例如[object setValue:forKey:]方法设置这些属性值,或者直接通过类型信息查询功能查出属性对应的实例变量在内存布局中的偏移量,以此来人为设置这个实例变量的值,但是这样做等于违规绕过了类中提供的API,可能会引发一些问题。

不要把可变的collection作为属性公开,而应提供相关方法,以此来修改对象中的可变collection。

第19条:使用清晰而协调的命名方式

方法名和变量名使用“驼峰式大小写命名法”(camel casing)——以小写字母开头,其他单词首字母都大写。类名也用驼峰命名法,不过首字母要大写,且前面通常还有两三个前缀字母。方法名不要使用缩略后的类型名称。

第20条:为私有方法名加前缀

给私有方法的名称加前缀,这样有助于调试,因此据此很容易就能把公共方法与私有方法区分开,也便于修改方法名或方法签名。

笔者喜欢用p_作为前缀,p代表private,而下划线可以将p与真正的方法名隔开;下划线后面的方法名首字母小写。不要单用一个下划线作为私有方法的前缀,因为这种做法是苹果公司预留使用的。

如果子类所继承的那个超类既不在苹果公司的框架中,也不在自己的项目中,而是来自于第三方框架,那么除非该框架在文档中明示,否则你无法知道私有方法的前缀是什么。这时可以将自己一贯使用的类名前缀作为子类私有方法的前缀,以避免重名问题。

第21条:理解Objective-C错误模型

ARC在默认情况下不是“异常安全”(exception safe)的。这意味着:如果抛出异常,那么本应在作用域末尾释放的对象现在却不会自动释放了。如果想要生成异常安全代码,可以通过设置编译器标志-fobj-arc-exceptions来实现,不过这将引入一些额外代码,在不抛出异常时也会执行。

只有发生了可令整个应用程序崩溃的严重错误时,才应抛出异常。在错误不那么严重的情况下,可以指派委托方法来处理错误,也可以把错误信息放到NSError对象里,经由“输出参数”返回给调用者。

第22条:理解NSCopying协议

要点:

若想要令自己写的对象具有拷贝功能,则需实现NSCopying协议。

如果自定义的对象分为可变版本与不可变版本,那么就要同时实现NSCopying协议与NSMutableCopying协议。

复制对象时需要决定采用浅拷贝还是深拷贝,一般情况下应该尽量执行浅拷贝。

如果你所写的对象需要深拷贝,那么可考虑新增一个专门执行深拷贝的方法。

你可能感兴趣的:(Objective,C,notes,objective-c)