编写高质量iOS有效方法总结(一)

1.Objective-C 起源

  • Objective-C 是 C 的 “超集”,所以 C 语言中的所有功能在编写 Objective-C 代码时依然适用。
  • Objective-C 使用“消息结构”而非“函数调用”。
//Messaging (Objective-C)
//消息结构其运行时执行的的代码由运行环境来决定
Object *obj = [Object new];
[ob performWith:parameter1 and: parameter2];


//Function calling (C++)
//函数调用则由编译器来决定
Object *obj = new Object;
obj->perform(parameter1, parameter2)
  • 在运行时编译器不关心接收消息的对象是何种类型,接收消息的对象问题也要在运行时处理,这个过程叫做“动态绑定”。
  • 所有 Objective-C 语言的对象都必须用 NSString * 这种类型声明,实际是一个指向 NSString 的指针。对象所占内存总是分配在堆空间(heap space)而不会在栈(stack)上。
    不能在栈上分配 Objective-C 对象:
 NSString stackString; 
//error: interface type cannot be statically allocated
  • 分配在堆中的内存必须直接管理,而栈上的内存则会在其栈帧弹出时自动清理。有时遇到定义里面不含有 * 的变量,可能会被分配到栈内存:
CGRect frame;
frame.origin,x = 10.0f;
  • 创建对象要比创建结构体有额外的开销(分配及释放堆内存),如果只需要保存非对象类型(int,float,double,char 等)使用结构体更高效。

2.在类的头文件中尽量少引入其他头文件

  • 向前声明(forward declaring)该类:在编译一个使用了 SomeClass 类的文件时,不需要知道 SomeClass 的全部细节,只需知道一个类名就好。
    @class SomeClass
    在 .m 实现文件则需要引入 SomeClass 类的头文件,因为要使用后者,则必须知道其所有接口的细节。
  • 将引入头文件的时机尽量延后,只有这确有需要时才引入,因为只要引入了 .h 文件就会一并引入这个类的所有内容,引入了许多用不到的内容会增加编译时间。
  • “循环引用”:在各自的头文件中引入对方的头文件。
    使用 #import 代替 #include 虽然不会导致死循环,但这却意味着两个类里有一个无法被正确编译。使用向前声明可以解决此问题。
  • 如果你写的类继承自某个超类,则必须引入定义那个超类的头文件。同理,如果你写的类尊循某个协议,那么该协议必须有完整的定义,不能使用向前声明,向前声明只能告诉编译器有某个协议,却不知道协议中的方法。尽量把该类遵循的协议声明到“分类”中。如果不行,就把该协议单独放在一个头文件中,然后将其引入。

3.多用字面量语法,少用与之等价的方法

  • 使用字面量语法可以缩减源代码长度,更易读,更整洁。
    NSArray *arrayA = [NSArray arrayWithObjects:@"dog", @"cat", @"badger", nil];
    NSString *cat = [arrayA objectAtIndex:1];
    
    NSArray *arrayB = @[@"dog", @"cat", @"badger"];
    NSString *cat = arrayA[1];
    
    NSDictionary *dicA = [NSDictionary dictionaryWithObjectsAndKeys:@"Matt", @"firstName", @"Galloway", @"lastname", [NSNumber numberWithInt:28], @"age", nil];
    NSDictionary *dicB = @{@"firstName":@"Matt", @"lastname":@"Galloway", @"age":[NSNumber numberWithInt:28]};

若 "cat" 变成 nil ,arrayA虽然能创建出来,但却只有 "dog" 一个对象。因为 arrayWithObjects 会依次处理各个参数,直到发现 nil 为止。同理 dictionaryWithObjectsAndKeys 方法也是一样。

  • 字典中的对象和键必须都是 Objective-C 对象,不能把整数直接放进去,要封装成NSNumber 实例才行。
  • 使用字面量语法创建出来的字符串,数组,字典对象都是不可变的,若要可变版本则需要复制一份:
NSMutableArray *mutable = [@[@1, @2, @3, @4] mutableCopy]; 

4.多用类型常量,少使用 #define 预处理指令

  • 很多时候定义一个动画执行时间会有这种写法:
    #define ANIMATION_DURATION 0.3
    假设这个指令声明在某个头文件中,那么所有引入了这个头文件的代码,其 ANIMATION_DURATION 都会被替换。也就是无意间可能替换了我们并不想替换的 ANIMATION_DURATION 。所以我们应该用编译器的特性来定义一个常量:
static const NSTimeInterval kAnimationDuration = 0.3;
  1. 常用命名法:若常量局限于某个 .m 文件之内,则在前面加字母 k ;若常量在类之外可见,则通常以类名为前缀。
  2. 这种命名法清楚地描述了常量的含义(包含类型信息)。
  3. 一定要同时使用 static 和 const 来声明:试图修改 const 声明的变量编译器会报错;static 修饰符意味着该变量仅在 .m 文件中可见。
  4. 如果不加 static ,编译器会创建一个外部符号,此时若其他 .m 中也声明了同名变量,编译器就会报错。
  • 对外公开的常量(比如通知中用到的 NSNotificationName )。其实注册者无须知道实际字符串的值,只需以常值比变量来注册自己想要接收的通知即可。此类常量应该放在全局符号表,以便可以定义该常量在 .m 文件之外。
//In the header file
extern NSString *const SomeClassNSNotificationName;

//In the implementation file
NSString *const SomeClassNSNotificationName = @"VALUE";

这是一个由常量指针修饰的 NSString 对象,不能够被修改。extern 关键字告诉编译器,在全局符号表中会有一个叫 SomeClassNSNotificationName 的符号,编译器无需查看其定义就允许代码使用,因为这个常量链接成二进制文件之后肯定能找到。此类常量只能定义一次,编译器会在数据段(全局区中的data区)为字符串分配存储空间。

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

推荐阅读更多精彩内容