编写高质量的OC代码--------熟悉Objective-C
来源:互联网 发布:h5能打开淘宝app吗 编辑:程序博客网 时间:2024/05/17 20:33
第1条:了解Objective-C语言的起源
1、Objective-C的消息结构
Objective-C使用“消息结构”而非“函数调用”。消息结构与函数调用的关键区别在于:使用消息结构的语言,其运行时所应执行的代码由运行环境来决定;而使用函数调用的语言,由编译器决定。如果函数调用是多态的,那么在运行时就要按照“虚方法表”来查出到底应该执行哪个函数实现。而采用消息结构的语言,不论是否多态,总是在运行时才会去查所要执行的方法。实际上,编译器甚至不关心接收消息的对象是何种类型。接收消息的对象问题也要在运行时处理,其过程叫做“动态绑定”。
2、Objective-C的运行时库
Objective-C的重要工作都由“运行时库”而非编译器完成的。运行时库提供了Objective-C的面向对象的能力,使用Objective-C的面向对象特性所需的全部数据结构及函数都是由“运行时库”提供的。举例来说,运行期组件中含有全部内存管理方法。
3、Objective-C的内存模型
Objective-C中的对象是以指针来指示的。想要声明一个变量,令其指代某个对象,可用以下语法:
NSString * someStr = @“The string”;
这种语法基本上是照搬C语言的,它声明了一个名为someString的变量,其类型是NSString*。也就是说,此变量为指向NSString的指针。所有Objective-C语言的对象都必须这样声明,因为对象所占内存总是分配在“堆空间”中,而绝不会分配在“栈”上。不能在栈中分配Objective-C对象。
如下代码:
NSString * someStr = @“The string”;
NSString * anothreStr = someStr;
只有一个NSString实例,然而又两个变量指向此实例。两个变量都是NSString* 型,这说明当前“栈帧”里分配了两块儿内存,每块内存的大小都能容下一枚指针(在32位架构的计算机上是4字节,64位计算机上是8字节)。这两块儿内存里的值都一样,就是NSString实例的内存地址。
分配在堆中的内存必须直接管理,而分配在栈上用于保存变量的内存则会在其栈帧弹出时自动清理。
Objective-C将对内存管理抽象了出来。不需要用malloc及free来分配或释放内存。Objective-C运行时环境把这一部分工作抽象为一套内存管理架构,名叫“引用计数”。
如果只是保存int、float、double、char等非对象类型,那么通常使用CGRect这种结构体就可以了。CGRect是C语言结构体。保存在栈上。整个系统框架都在使用这种结构体,因为如果改用Objective-C对象来做的话,性能会受到影响。与创建结构体相比,创建对象还需要额外开销,例如分配及是否堆内存等。
第2条:在类的头文件中尽量少引用其他头文件
1. 将引入头文件的时机尽量延后,只在确有需要时才引入,这样就可以减少类的使用者所需引入的头文件梳理。缩短编译时间。
2. 向前声明可以解决两个类循环引用的问题,当两个类循环引用的时候。使用#import而不是#include虽然不会导致死循环,但却意味着两个类里有一个无法被正确编译。
3. 有时候必须要在头文件中引用其他头文件。如果你写的类继承自某个超类,则必须引入定义那个超类的头文件。同理,如果要声明你写的类继承自某个超类,那么必须由完整的定义,且不能使用向前声明。向前声明只能告诉编译器有某个协议,而此时编译器却要知道该协议中定义的方法。所以协议通常声明在一个单独的文件中(代理协议除外,代理协议单独声明是没有任何意义的)。
第3条:多用字面量语法,少用与之等价的方法
字面量语法实际上只是一种“糖衣语法”,其效果与常规语法等效但是开发者用起来却更加方便。“糖衣语法”可令程序更易读,减少代码出错几率。
要点:
1、应该使用字面量语法来创建字符串、数值、数组、字典。与创建此类对象的常规方法相比,这么做更加简明扼要。
2、应该通过取下标操作来访问数组下标或字典中的键所对应的元素。
3、用字面量语法创建数组或字典时,若值中有nil,则会抛出异常。因此,务必确保值里不含nil。
字面量语法的局限性:
1、所创建出的对象必须属于Foundation框架。要想创建自定义子类实例,必须采用“非字面量语法”。
2、字面量语法创建出来的字符串、数组、字典对象都是不可变的。若想要可变版本的对象,则需赋值一份:
NSMutableArray * mutable = [@[@1,@2,@3,@4]mutableCopy];
第4条:多用类型常量,少用#define预处理指令
以如下预处理为例为例:
#define ANIMATION_DURATION0.3
1、预处理指令不携带类型信息,类型常量携带类型信息。
2、预处理指令作用域不明确,假设该指令声明在某个头文件中,那么所有引入了这个头文件的代码,其ANIMATION_DURATION都会被替换。
3、即使有人重新定义了常量值,编译器也不会产生警告,这将导致应用程序中的常量值不一致。
在实现文件中定义“只在编译单元内可见的常量”
staticconstNSTimeInterval kAnimationDuration =0.3;
变量一定要同时用static和const来声明。const确保变量不可变,static则意味着该变量仅在定义此变量的编译单元中可见。假如声明此变量时不加static,则编译器会为它创建一个“外部符号”。此时若是另一个编译单元中也声明了同名变量,那么编译器会报错。实际上,若干一个变量即声明为static,又声明为const,那么编译器根本不会创建符号,而是会像#define预处理指令一样,把所有遇到的变量都替换为常值。不过还是要记住:用这种方式的常量带有类型信息。
有时需要对外公开某常量。此类常量需放在“全局符号表”中,以便可以在定义该常量的编译单元之外使用。应该这样来定义
//In the header file
externNSString *const EOCStringConstant;
externNSString *const EOCStringConstant;
//In the implementation file
NSString *const EOCStringConstant =@"VALUE";
NSString *const EOCStringConstant =@"VALUE";
这种常量要出现在全局符号表中,所以其名称应加以区隔,通常用与之相关的类名做前缀。总之,勿使用预处理指令定义常量,而应借助编译器来确保常量正确。
第5条:枚举的使用
C++11标准修订了枚举的某些特性。其中一项改动是:可以指明用何种“底层数据类型”来保存枚举类型的变量。这样做的好处是,可以向前声明枚举变量了。若不指定底层数据类型,则无法向前声明枚举类型。因为编译器不清楚底层数据类型的大小,所以在用的此枚举类型时,也就不知道究竟该给该变量分配多少内存空间。
如果把传递给某个方法的选项表示为枚举类型,而多个选项又可同时使用,那么就将各选项值定义为2的幂,以便通过按位或操作将其组合起来。
用NS_ENUM与NS_OPTIONS宏来定义枚举类型,并指明其底层数据类型。这样做可以确保枚举是用开发者所选的底层数据类型实现出来的,而不会采用编译器所选的类型。
在处理枚举类型的switch语句中不要实现default分支。这样的话,加入新枚举之后,编译器就会提示开发者:switch语言并未处理所有枚举
阅读全文
0 0
- 编写高质量的OC代码--------熟悉Objective-C
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- Objective-C你了解吗--如何编写高质量有效的OC代码
- 编写高质量OC代码52建议总结:21.理解Objective-C的错误模型
- 编写高质量Objective-C代码
- [iOS]编写高质量的Objective-C代码
- 如何编写高质量的oc代码
- 编写高质量oc代码
- Objective-C编写高质量代码 字面量语法
- Objective-C编写高质量代码 字面量语法
- tomcat7+jdk的keytool生成证书 配置https
- 学会使用5W1H来写作博客
- ArcGIS 10.2生成渔网(fishnet)
- Apache的一些配置
- EJB解析
- 编写高质量的OC代码--------熟悉Objective-C
- 地球空间与数字测绘知识总结
- ArcGIS 10.2中栅格数据的属性表问题
- Eclipse 的快捷键以及文档注释、多行注释的快捷键
- SQL注入及SQLmap使用
- hdu2527 Safe Or Unsafe 哈夫曼树
- 解析C#多线程编程中异步多线程的实现及线程池的使用
- 解决ArcGIS 9.3卸载时出现invalid install.log file的方法
- Lucene--搜索