第一章 熟悉Objective -C   编写高质量iOS与OS  X代码的52 个有效方法

 

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

关键区别在于 :使用消息结构的语言,其运行时所应执行的代码由运行环境来决定。而使用函数调用的语言,则由编译器决定。如果范例代码中调用的函数是多态的,那么在运行时就要按照虚方法表 virtual table 来查出到底应该执行那个函数实现。而采用消息结构的语言,不论是否多态,总是在运行时才会去查找所要执行的方法。

实际上,编译器甚至不关心接受消息的对象是何种类型。接受消息的对象问题也要在运行时处理,其过程叫做动态绑定 dynamic binding .

 

 

Objective -C 语言中的指针是用来指示对象的。

对象所占内存总是分配在堆空间 heap space 中,而绝不会分配在栈stack 上。不能在栈中分配对象。

 

NSString *someString =@"The string";

someString 变量指向分配在堆里的某块内存,其中含有一个NSString 对象。也就是说,如果再创建一个变量,令其窒息那个同一地址,那么并不拷贝该对象,指示这两个变量同时指向此对象。

 

NSString *someString =@"The string";

NSString *anotherString=someString;

 

两个变量都是NSString* 型。这说明当前 stack frame 栈 帧里分配了两块内存,每块内存的大小都能容下一枚指针。

这两块内存的值都一样,就是NSString实例的内存地址。

分配在堆中的内存必须直接管理,而分配在栈上用于保存变量的内存则会在其栈帧弹出时自动清理。

 

Objective -C 将堆内存管理抽象出来了。不需要用malloc 以及free来分配或释放对象所占内存。Objective-C运行期环境把这部分工作抽象出来为一套内存管理架构。叫做引用计数 reference couting .

在Objective -C 中,有时会遇到定义里不含* 的变量,他们可能会使用栈空间 stack space .这些变量所保存的不是Objective-C 对象。

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

 

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

字符串字面量 string literal 其语法是

NSString * someString =@"HAHA";

使用字面量语法literal syntax 可以缩减源代码长度,使其更为易读。

字面数值 有时需要把整数、浮点数 、布尔值封入OC 对象中,这种情况下可以用NSNumber类。

NSNumber *someNumber=[NSNumber numberWithInt :1];

可以这样写

NSNumber *someNumber=@1;

 

第四条:多用类型常量 ,少用#define 预处理指令

编写代码时经常要定义常量 。

#define ANIMATION_DURATION 0.3 

定义出来的常量没有类型信息。 

要想解决此问题,应该设法利用编译器的某些特点才对。有个办法比用预处理指令来定义常量更好。

static const NSTimeInterval kAnimationDuration =0.3;

请注意,用此方法定义常量包含类型信息,其好处是清楚的描述了常量的含义。

如果要定义许多常量,那么这种方式能令阅读代码的人更易理解其意图。

常用的命名法是:若常量局限于某编译单元 translation unit 也就是实现文件 implementation file 之内,则在前面加字母k。若常量在类之外可见,则通常以类名为前缀。

 

定义常量的位置很重要。 我们总喜欢在头文件里声明预处理指令,这样做不好。当常量名称有可能冲突时更是如此。例如 ,ANIMATION_DURATION 这个常量的名字就不该出现在头文件中,因为所有引入了这份头文件的其他文件都会出现这个名字,其实就连static const 定义的常量也不应该出现在头文件中。因为OC 中没有命名空间 namespace 这一概念。所以那样做都等于声明了一个名叫kAnimationDuration 的全局变量。此名称应该加上前缀,以表明其所属的类,例如可改为EOCViewClassAnimationDuration .

若不打算公开某个常量,则应将其定义在使用该变量的实现文件中。

变量一定要同时用static 与const  来声明。如果试图修改由const 修饰符所声明的变量,那么编译器就会报错。而 static 修饰符则意味着该变量仅在定义此变量的编译单元中可见

编译器每收到一个编译单元,就会输出一份目标文件。在OC的语境下,编译单元一次通常指每个类的实现文件(以.m为后缀名)。因此,在上述范例代码中声明的kAnimationDuration变量,其作用域仅限于由EOCAnimatedView.m 所生成的目标文件中。

假如声明此变量时不加static ,则编译器会为它创建一个外部符号external symbol .此时,若是另一个编译单元也声明了同名比阿娘,那么编译器就会抛出一条错误消息:

 

实际上,如果一个变量声明为Static,又声明为const ,那么编译器根本不会创建符合,而是会像#define 预处理指令一样,把素有遇到的变量都替换为常值。

 

有时候需要被外部使用,此类变量需放在全局符号表 global symbol table 中,以便可以在定义该常量的编译单元之外使用。因此,其定义方式与static const 有所不同。应该是这样定义: 

 

 

常量定义从右至左解读,所以在本例中,EOCStringConstant 就是一个常量,而这个常量是指针,指向NSString 对象。

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

新版系统框架中使用了 强类型 strong type 的枚举。

枚举只是一种常量命名方式。某个对象所经历的各种状态可以定义为一个简答的枚举 enumeration set .

由于每种状态都用一个便于理解的值来表示,这样写出来的代码更容易理解。

 

第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法的更多相关文章

  1. iOS书摘之编写高质量iOS与OS X代码的52个有效方法

    来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...

  2. 笔记 《Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法 》

    阅读此书的笔记点: 此书目录即是对知识点最好的总结 第1章 熟悉Objective-C ---------------------------------------------- 第1条:了解Obj ...

  3. 编写高质量iOS与OS X代码的52个有效方法

    第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...

  4. 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》

    1.Objective-C 起源: 在 C 语言基础上添加了面向对象特性,是 C 语言的超集.Objective-C 由 SmallTalk 语言演变过来,使用消息结构,运行环境由运行环境决定. OC ...

  5. 《编写高质量iOS与OS X代码的52个有效方法》书籍目录

    一.熟悉Objective-C 1.了解Objective-C语言的起源 2.在类的头文件中尽量少引入其他头文件 3.多用字面量语法,少用与之等价的方法 4.多用类型常量,少用#define预处理指令 ...

  6. 编写高质量iOS代码与OS X代码的effective 方法小结

    一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用  消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ...

  7. <笔记>Effective Objective-C 2.0 编写高质量iOS与

    1. 内存管理-引用计数 2. 非对象类型  int float double char 3.运行时--编译器(编译时)函数调用 4.@class  缩短编译时间,降低依赖,耦合 5.使用字面量而不是 ...

  8. 编写高质量iOS代码与OS X代码的effective方法(小结)

    一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用  消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ...

  9. 编写高质量iOS代码的52个有效方法2-1

    一.变量的定义位置(用{}声明示例变量或者用@property属性声明实例变量) 1.用{}声明示例变量: 此方法生命的实例变量,编译器在编译时,会自动计算其偏移量(表示该变量距离存放对象的内存区域的 ...

随机推荐

  1. Scanner、String(java基础知识十二)

    1.Scanner的概述和方法介绍 * A:Scanner的概述 * 是一个从键盘输入的类,有final修饰,不能被子类继承 * Scanner sc = new Scanner(System.in) ...

  2. 数组、栈、堆(java基础知识五)

    1.数组概述.定义格式 * A:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数据类型,也可以存储引用数据类型. * B:数组定义格式 格式1:数据类型[ ...

  3. hdu acm 2844 Coins 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2844 题目意思:有A1,A2,...,An 这 n 种面值的钱,分别对应的数量是C1,C2,...,C ...

  4. 666 专题三 KMP &#38; 扩展KMP &#38; Manacher

    KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...

  5. Oracle中如何用SQL检测字段是否包括中文字符

    用Oracle的编码转换的函数Convert实现,测试后可行. SQL> select *  2    from (select 'abcd' c1 from dual  3          ...

  6. hdu-5675 ztr loves math(数学)

    题目链接: ztr loves math  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Othe ...

  7. codeforces 414B B. Mashmokh and ACM(dp)

    题目链接: B. Mashmokh and ACM time limit per test 1 second memory limit per test 256 megabytes input sta ...

  8. 90年代经典“手游”—拼图板小游戏Opencv实现

    80后可能还对儿时玩过的一种经典木质的拼图板游戏记忆犹新,一般是一种4*4或5*5规格的手持活动板,通过挪动每个小板子的位置,拼出来板子上完整的图像,那时候还没有网吧,手机也还是大哥大的天下,所以这也 ...

  9. bzoj 2836 魔法树 —— 树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836 树链剖分裸题: 写码五分钟,调码两小时,RE不断,狂交二十五遍,终于找到一处小细节—— ...

  10. Android应用开发完全退出程序的通用方法

    在开发一个android应用时,有可能有N个Activity,而在每个Activity里的菜单里有个"退出程序"菜单,这里就要完全退出程序了,所以今天给大家分享的是Android应 ...