第三章 接口与API设计(EffectiveObjective-C)

1 使用前缀避免命名空间冲突

  • 命名冲突,应用程序链接的时候会报错
    duplicate symbol _OBJC_METACLASS_$_EOCTheClass in: build/somthing.o
    在运行期载入了含有重名类的程序库,"动态加载"遭遇"重名符号错误",会导致程序崩溃
  • 不仅是类名,应用程序中的所有名称都应加前缀,如果要为既有类新增"分类"(category),那么一定要给"分类"及"分类"中的方法加上前缀
  • 如果用第三方库编写自己的代码,并准备将其发布为程序库供其他人开发应用程序所用.
    这是应该给你所用的那一份第三非苦代码加上你自己的前缀.
    例如:你准备发布的程序库叫做EOCLibrary.

2 提供"全能初始化方法"

为对象提供必要信息以便其完成工作的初始化方法叫做"全能初始化方法"
UITableViewCell,在初始化该类对象时,需要指明其样式以及标识符
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier
如果创建类实例的方式不止一个,那么这个累就会有很多个初始化方法,不过仍然要在其中选定一个作为全能初始化方法,令其他初始化方法都来调用他
好处:当底层数据存储机制改变时,只需修改此方法的代码就好,无须改变其他初始化方法

3 现实description方法

description:在NSObject协议中,自定义NSLog方法返回的字符串
debugDescription:在NSObject协议中,自定义在控制台通过po命令输出的的字符串

4 尽量使用不可变对象

  • 设计类的时候,应充分应用属性来封装数据,而在使用属性时,则可将其声明为"只读"(read-only).
    默认情况属性是"可读可写"(read-write).这样设计出来的类是"可变的".
    在编程实践中,则应该尽量把对外公布出来的属性设为只读,而且只在确有必要时才将属性对外公布
@interface EOCPointOfInterest : NSObject
@property (nonatomic, copy,readonly) NSString *indentifier;
@property (nonatomic, copy,readonly) NSString *title;
@end
  • 有时可能想要修改封装在对象内部的数据,但是却不想令这些数据为外人所改动.这个时候,通常做饭是在对象内部将readOnly属性重新什么为readwrite,当然属性是nonatomic的,那么这样做可能会产生"竞争条件"(race condition).可以通过"派发队列"等手段,讲数据存取设为同步操作
#import "EOCPointOfInterest.h"
@interfaceEOCPointOfInterest ()
@property (nonatomic, copy,readwrite) NSString *indentifier;
@property (nonatomic, copy,readwrite) NSString *title;
@end

@implementation EOCPointOfInterest
@end
  • 不要把可变的collection作为属性公开,而应该提供相关方法,以此修改对象中的可变collection
    Person有个friends的集合属性
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong,readonly) NSSet *friends;
- (void)addFriend:(Person*)person;
- (void)removeFriend:(Person*)person;
@end

@implementation Person{    
  NSMutableSet *_internalFriends;
}

- (NSSet *)friends{    
  return [_internalFriendscopy];
}
- (void)addFriend:(Person *)person{   
    [_internalFriendsaddObject:person];
}
- (void)removeFriend:(Person *)person{ 
   [_internalFriendsremoveObject:person];
}
@end

5 使用清晰而协调的命名方式

方法与变量名使用"驼峰式大小写命名法",变量名小写字母开头,其后每个单词首字母大写
类名首字母要大写,其后每个单词首字母大写.
5.1 方法命名

  • 如果方法的返回值是新创建的,那么方法名的首个词应该是返回值类型,除非前面还有修饰语
  • 应该把标识参数类型的名词放在参数前面
  • 如果方法要在当前对象上执行操作,那么就应该包含动词,若执行操作时还需要参数,则应该在动词
    后面加上一个或多个名词
  • 不要使用str这种简称,应该用string这样的全称
  • Boolean属性应加is当前缀.如果某方法返回非属性的Boolean值,那么应该根据其功能选用
    has或is做前缀
  • 将get这个前缀留给哪些借由"输出参数"来保存返回值的方法.

5.2 类与协议的命名
应该为类与协议的名称加上前缀,以避免命名控件冲突

6 为私有方法名加前缀

  • 一个类所做的事情通常都要比从外面看到的更多,编写类的实现代码时,经常要写一些只有内部使用
    的方法,建议为这种方法的名称加上某些前缀, 这样有助于调试, 这样能很容易把公共与私有方法分开
  • 为私有方法添加前缀的好处二:修改其名称或签名之前要三思,公共API不便轻易改动(影响面广)
  • 具体使用何种前缀根据个人喜好,其中最好包含下划线与字母, 如p_作为前缀
@interface EOCObject : NSObject
- (void)publicMethod;
@end
@implementation EOCObject
- (void)publicMethod{}
- (void)p_privateMthod{}
@end
  • 不要单用一个下划线做私有方法的前缀,因为这种做法是预留给苹果的

7 理解Objective-C 错误类型

7.1 Objective-C:只在极其严重的错误下抛出异常,抛出异常之后,无需考虑回复问题,而且应用程序此时也应该退出
7.2 在非致命错误:Objective-C所采用的方式是令方法返回nil/0. 或是使用NSError,以表明其中有错误发生
7.3 NSError对象里封装了三条消息

  • Error domain:错误范围,也就是产生错误的根源.类型为字符串,通常用一个特有的全局变量来定义
  • Error code:错误码,类型为这个整数.用意指明具体发生了何种错误,通常采用enum来定义
  • User info:用户信息,类型为字典,关于错误的额外描述,包含一段"本地化描述"
    NSError第一种常见用法就是通过协议,来传递错误.有错误发生时,当前对象会把错误信息经由协议中的某个方法传递给委托对象(delegate)
    NSError第二种常见用法:经由方法的"输出参数"返回给调用者.
- (BOOL)doSomething:(NSError *__autoreleasing *)error{
  //do somethong that may cause an error   
 if (/*there was an error*/) {
        if (error) {
          *error = [NSErrorerrorWithDomain:domaincode:codeuserInfo:userInfo];
        }        
      returnNO;  
  }   
   returnYES;
}

传递给方法的参数是个指针,而该指针本事又指向另外一个指针,而该指针本身又指向另外一个指针,
那个指针指向NSError对象,或者也可以把他当成一个直接指向NSError对象的指针.这样一来,就可以经由
"输出参数"把NSError对象传递给调用者

NSError *error=nil;
[selfdoSomething:&error];

8 理解NSCoping协议

如果想自己的类支持拷贝操作,那就要实现NSCopying协议,该协议只有一个方法
- (id)copyWithZone:(NSZone *)zone;
long long age,会据此把内存分成不同的"区"(zone),而对象会创建在某个区里面,现在每个程序只有一个去,
"默认区"(default zone).所以在实现这个方法的时候,不用考虑参数zone.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容