《Effective OC》精读笔记(1)—— 熟悉OC

第一章:熟悉OC


第一条:OC是消息型语言,使用“消息结构”而非“函数调用”。

        消息调用与函数的区别:

        1.消息型语言运行时所执行的代码由编译时的环境决定而非编译器,这也就是说运行时才会检查对象类型,也就是我们常说的:runtime 运行时机制

        2.从code中看OC的语法常用方括号:[ ] ,而其他语言多用->。


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

        创建一个类你需要:

        1.OC使用:头文件(header file)和实现文件(implementation file)来区隔代码。也就是我们常说的.h文件和.m文件,.h文件用于类的声明,而.m文件用于类的实现。

        2.@class和#import的区别:

        #import可以把目标类的全部细节拿出来传给所需文件。

        @class只搞给目标有一个这样的文件,而不知道其细节。(这叫做“向前声明”该类)

        我们一般在.h文件中写@class在.m中使用#import,这样就有效的降低耦合度,避免循环使用。

         无法使用“向前声明”时,比如我们想要某个类遵循一项协议时,我们需要把协议声明放到“class continuation分类”中,如果这样还不行的话,那我们需要把协议放到一个头文件中,然后将其引用。关于“class continuation分类”可以读这篇文章:协议与分类


第三条:多用字面量语法,少用与之等价的语法。

        OC以语法繁杂而著称,为了真强语法的易读性,我们在编程时间应该尽可能的使用“字面量语法”来避免“alloc”和“init”来为我们分配并初始化内存。什么是“字面量语法呢”,下面我来举一些栗子给大家:

 1.字符串字面量

NSString * str = [[NSString alloc]initWithString:@"string"];

NSString * strZML = @"string";

2.字面量数值

NSNumber * numInt = [[NSNumber alloc]initWithInt:3];

NSNumber * numChar = [[NSNumber alloc]initWithChar:'a'];

NSNumber * numBool = [[NSNumber alloc]initWithBool:YES];

NSNumber * ZMLnumInt = @1;

NSNumber * ZMLnumChar = @'a';

NSNumber * ZMLnumBool = @YES;

3.字面量数组

NSArray * arr = [[NSArray alloc]initWithObjects:[NSString stringWithFormat:@"abc"],[[NSNumber alloc]initWithInt:1], nil];

NSString * str = [arr objectAtIndex:0];

NSArray * ZMLarr =@[@"abc",@1];

NSString * ZMLstr = arr[0];

        用initWithObjects处理时,当元素有nil,方法会提前结束。而如果用字面量创建的数组,元素中有nil,则会抛出异常。提高代码的安全性。

        在这个时候,作者提到了“语法糖”这一术语,大概意思是指,在计算机中与另一套语法等效开发者用起来更方便的语法。有兴趣的朋友可以看看这篇文章:[IOS黑魔法] - 语法糖

4.字面量字典

NSDictionary * dic = [[NSDictionary alloc]initWithObjectsAndKeys:@"hehe",@"name",[[NSNumber alloc] initWithInt:1],@"age", nil];

NSDictionary *ZMLdic = @{@"hehe":@"name",@1:@"age"};

       很奇怪,用initWithObjectsAndKeys来创建的字典对象录如数据的顺序是:<对象>,<键>,<对象>,<键>这样的。而用字面量这用@{@“”:@“”},把键映射到对象的格式让人看上去很舒服。

5.可变对象

       由于字面量创建出来的对象是默认不可变的,如果想要创建可变对象的话也很简单,调用mutableCopy方法即可,如以下code:

NSMutableString * str = [@"aaaaa" mutableCopy];

NSMutableArray * arr = [@[@"aaa",@"bbb",@"ccc"] mutableCopy];

NSMutableDictionary *dic = [@{@"hehe":@"name",@1:@"age"} mutableCopy];

6.局限性

        除了字符串以外,对象必须是Foundation框架下的才可以。如果是自定义这些类的自类则无法使用字面量!针对这一点作者也给出了解决办法,就是自定义Foundation的子类,但是这样做成本太高,而且比较麻烦,所以并没有建议读者去这么做。


第四条:多用类型常量,少用#define

         预处理指令:#define 我们可以用它来定义常量,但是有一下两个问题:

        1.用#define创建出来的常量不含有类型信息,编译器只会这编译前据此执行查找与替换这样简单的工作。

         2.用#define创建出来的常量值可以被重新定义,编译器并不会发出相应的警告信息。

         3.常量命名:若常量局限于某个编译单元也就是.m文件中,则在前面加k。若常量在类之外可 见,则通常以类名为前缀。

        综上所诉,作者反对使用#deine来创建常量值,而是建议读者在.m文件中使用 static const 来定义常量,这样做的好处是:

        1.有static的存在,保证了只在编译单元内可见,并不在全局编译表中。

        2.static 与 const 混用编译器会像#define那样将所有出现的变量替换为常值,而且带有类型信息!

        若要在.h文件中定义全局常量,应使用extern来定义。这样当编译器看到.h文件中有extern开头的常量就会明白这个全局变量要放到全局符号表中。注意:为了避免用命重复,使用相关类名做为前缀。

//定义.h文件中的全局变量

extern NSString * const VCstring; //指针类型

extern const NSTimeInterval VClongTime;  //其他类型

//.m中给其赋值

NSString * const VCstring = @"ID";

const NSTimeInterval VClongTime = 30;

        想要详细了解宏定义的童鞋,推荐看喵神写的这篇文章:宏定义的黑魔法 - 宏菜鸟起飞手册

第五条:用枚举表示状态,选项,状态码

1.用枚举表示状态

        当程序中需要定义对象的不同状态,我们通常会用一些常量来标记一些东西。这时如果你用一个枚举来表示出来这些状态则会优雅许多。下面我举一个友盟框架中的一个枚举栗子:

/**QQ消息类型*/

typedef enum {

UMSocialQQMessageTypeDefault,    //非纯图片QQ消息

UMSocialQQMessageTypeImage        //纯图片QQ消息

}UMSocialQQMessageType;

可以看到:友盟分享在区分消息类型是纯图片还是非纯图片状态时,就用了枚举值来处理:

a.用UMSocialQQMessageTypeDefault这一常量来标记了非纯图片QQ消息。

b.用UMSocialQQMessageTypeImage这一常量来标记了纯图片QQ消息。

c.用typedef给枚举值取了一个别名:UMSocialQQMessageType来方便调用:

/**分享到QQ好友的消息类型*/

@property (nonatomic, assign) UMSocialQQMessageType qqMessageType;


NS_ENUM: NS_ENUM 的第一个参数是用于存储的新类型的类型。在64位环境下,UITableViewCellStyle 和 NSInteger 一样有8bytes长。你要保证你给出的所有值能被该类型容纳,否则就会产生错误。第二个参数是新类型的名字。大括号里面和以前一样,是你要定义的各种值。

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {

UITableViewCellStyleDefault,

UITableViewCellStyleValue1,

UITableViewCellStyleValue2,

UITableViewCellStyleSubtitle

};


2.用枚举表示选项

        当我在程序中定义选项时,尤其在定义可以组合的选项时,我们更应该学会枚举去定义你的选项列表,这样可以用“按位或操作符”来去组合你的选项。这些东西常常在许多第三方框架中出现,如果还不了解的同学可以看看这篇文章:枚举值定义选项通过按位或来实现多选,写的挺不错的。好了,接下来让我们看看具体的实现过程,就拿

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

推荐阅读更多精彩内容