《Effective Obejctive-C2.0编写高质量iOS和OSX代码的52个有效方法》读书笔记--持续更新中...

注:转载请附上原作者及其链接

第一条:了解Objective-C语言起源

Smalltalk 消息型语言的鼻祖

函数调用语言:由编译器决定
消息结构语言:由运行环境决定
“动态绑定”在运行时才会检查对象类型
“运行期组件”

指针 32位计算机4字节 64位计算机8字节

相比C语言,Objective-C将堆内存管理抽取出来,不需要用malloc和free来分配或释放对象所占内存 — 内存管理架构(引用计数)

例如 CGRect 这种结构体如果改用Objective-C对象来做的话,性能会受影响:创建对象需要额外开销—分配释放堆内存等
结构体分配的内存在栈上,不需要上层管理

第二条:在类的头文件中尽量少引入其他头文件

C C++ OC 头文件+实现文件

这也是编程思想的一种体现,可以说.h和.m文件时完全独立的,只是为了要求有较好的可读性,才要求两个文件的文件名一致,这也是把接口和实现分离,让调用者不必去关心具体的实现细节。

向前声明 @class 告诉编译器某个类存在

Snip20170623_4.png

第三条:多用字面量语法(即“语法糖”)

  • 数值
NSNumber *num = [NSNumber numberWithInt:1 ];
// 语法糖形式:
 NSNumber *num = @"1";
  • 数组
NSArray *animals = [NSArray arrayWithObjects:@"cat",@"dog",nil];
// 语法糖形式:
NSArray *animals = @[@"cat",@"dog"];

取元素

NSString *dog = [animals objectAtIndex:1];
// 语法糖形式
NSString *dog = animals[1];

一个小细节:


Snip20170623_5.png
  • 字典
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
      @"ma":@"firstName",
      @"yun":@"secondName",
      [NSNumber numberWithInt:28:@"age",
nil]];
// 语法糖形式:
NSDictionary *dict = @{
            @"firstName":@"ma",
            @"secondName":@"yun",
            @"age":@28
};
  • 可变数组和可变字典

取元素替换元素

[mutableArray replaceObjectAtIndex:1 withObject:@"dog"];
[mutableDict setObject:@"hello" forKey:@"lastName"];
// 语法糖
mutableArray[1] = @"dog";
mutableDict[@"lastName"] = @"hello" ;
NSMutableArray *arr = [@[@"1",@"2"] mutableCopy];

第四条:多用常量 ,少用宏

比如把一个动画的播放时长提取出来,如果使用宏有个缺点-没有类型信息

#define ANIMATION_DURATION 0.3;
static const NSTimeinterval kAnimationDuration  = 0.3;

第六条:理解“属性”这一概念(理解@property)

实例变量和@property

@property可以分为四类:

  • 原子性
  • 读写权限
  • 内存管理语义
  • 方法名

第七条:在对象内部尽量直接访问实例变量

第十一条:对象消息 传递 机制

静态绑定:C语言采用的方式
动态绑定: OC采用的方式
选择器(选择子)
消息:选择器+参数

动态消息派发系统:编译器调用objc_msgSend将消息转为标准的C语言函数调用

// 消息机制中的核心函数
objc_msgSend
// 边界情况处理函数
objc_msgSend_stret
objc_msgSend_fpret
objc_msgSendSuper

大致过程:

id returnValue = [someObject messageName:parameter:];
// 编译器转换为如下函数
id returnValue = objct_msgSend(someObject,
                  @selector(messageName:),
                  parameter);
// objct_msgSend会在接收者所属类中的“方法列表”中查找方法实现
// 查找会有缓存 -- 快速映射表
Snip20170627_14.png

第十二条:对象消息 转发 机制

对象在收到无法解读的消息之后怎么办?

动态方法解析(所属类能否动态添加方法来处理选择器) --> 看有无“备援接收者” --> 启动完整的消息转发机制

动态方法解析:

+ (BOOL)resolveInstanceMethod:(SEL)selector; // 未实现的方法是示例方法
+ (BOOL)resolveClassMethod:(SEL)selector;// 未实现的方法是类方法

第十四条:理解“类对象”的用意

第三章 接口和API设计

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

OC没有命名空间机制,所以我们应该设法避免命名冲突,否则很容易重名,命名冲突会在链接的时候报错

  • 苹果宣称保留两个字母前缀使用的权利,建议使用三个字母(感觉没有啥必要,前缀起名稍微注意一下就可以了);
  • 在将代码发布为程序库的时候尤其要注意给函数等加上前缀,否则很容易造成命名冲突而报“重复符号错误”,代码中用到了其他第三方库也要将第三方库的前缀一并修改统一;

第十六条:提供“全能初始化方法”

Snip20170626_13.png

EOCSquare和ECORectangle例子

// 抛出异常
- (id)initWithWidth:(float)width andHeight:(float)height{
  @throw[NSException exceptionWithName: NSInternalInconsistencyException
      reason:@"Must be initWithDimension:instead.",
    userInfo:nil];
}

第十七条:实现description方法

在构建需要打印到日志的字符串的时候,object会收到description消息

  • 把待打印的信息放在字典里
Snip20170626_12.png
  • description 和 debugDescription


    Snip20170626_10.png

第十八条:尽量使用不可变对象(即readonly的应用场景)

Snip20170626_9.png

第十九条:命名规范

首先OC方法的冗长也是有好处的,可以清晰表达出意图,对比其他语言:

NSString *newText = [text stringByReplacingOCcurrenceOfString:@"fox"
                                                    withString:@"cat"];
// java中
string newText = text.replace("fox","cat");
  • 方法命名
错误示例:
CYRectangle *rectangle = [[CYRectangle alloc] initWithSize:5.0f :10.0f];
正确示例:
CYRectangle *rectangle = [[CYRectangle alloc] initWithWidth:5.0f andHeight:10.0f];

第二十条:为私有方法加前缀

@interface CYObject : NSObject
- (void)publicMethod;
@end 
@implemention CYObject
- (void)publicMethod{
}
// 加前缀
- (void)p_privateMethod{
}
@end

原因:

  • 便于区分公共方法和私有方法;
  • 公共API一般不要轻易改名字,改了可能别的开发者要更新代码,给私有方法加前缀很容易看出哪些方法可以随意改动,哪些方法不可以;

注意:苹果公司喜欢用一个单一的下划线作为私有方法的前缀,所以要求开发者不应该使用作为私有方法的前缀,否则在继承的时候无意的覆盖了父类的方法

第五章:内存管理

第二十九条:理解引用计数
第三十条:以ARC简化引用计数
第三十一条:在dealloc方法中只释放引用并解除监听
第三十二条:编写“异常安全代码”时,留意内存管理问题
第三十三:以弱引用避免保留环
第三十四:以“自动释放块池”降低内存峰值
第三十五:用“僵尸对象”调试内存管理问题
第三十六:不要使用retainCount
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容