第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法
第一章 熟悉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 个有效方法的更多相关文章
- iOS书摘之编写高质量iOS与OS X代码的52个有效方法
来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...
- 笔记 《Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法 》
阅读此书的笔记点: 此书目录即是对知识点最好的总结 第1章 熟悉Objective-C ---------------------------------------------- 第1条:了解Obj ...
- 编写高质量iOS与OS X代码的52个有效方法
第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...
- 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》
1.Objective-C 起源: 在 C 语言基础上添加了面向对象特性,是 C 语言的超集.Objective-C 由 SmallTalk 语言演变过来,使用消息结构,运行环境由运行环境决定. OC ...
- 《编写高质量iOS与OS X代码的52个有效方法》书籍目录
一.熟悉Objective-C 1.了解Objective-C语言的起源 2.在类的头文件中尽量少引入其他头文件 3.多用字面量语法,少用与之等价的方法 4.多用类型常量,少用#define预处理指令 ...
- 编写高质量iOS代码与OS X代码的effective 方法小结
一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用 消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ...
- <笔记>Effective Objective-C 2.0 编写高质量iOS与
1. 内存管理-引用计数 2. 非对象类型 int float double char 3.运行时--编译器(编译时)函数调用 4.@class 缩短编译时间,降低依赖,耦合 5.使用字面量而不是 ...
- 编写高质量iOS代码与OS X代码的effective方法(小结)
一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用 消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ...
- 编写高质量iOS代码的52个有效方法2-1
一.变量的定义位置(用{}声明示例变量或者用@property属性声明实例变量) 1.用{}声明示例变量: 此方法生命的实例变量,编译器在编译时,会自动计算其偏移量(表示该变量距离存放对象的内存区域的 ...
随机推荐
- YTU 2419: C语言习题 等长字符串排序
2419: C语言习题 等长字符串排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 650 解决: 249 题目描述 在主函数中输入n(n<=10)个等长的字符串.用另一函数对 ...
- java24点算法
输入任意的四个数,求出所有能得到二十四点的算式,不过我是菜鸟,可能性能方面不好,希望各位多多指教1. [代码][Java]代码 import java.util.ArrayList;impo ...
- codeforces 667A A. Pouring Rain(水题)
题目链接: A. Pouring Rain time limit per test 1 second memory limit per test 256 megabytes input standar ...
- JS截取与分割字符串常用技巧总结
本文实例讲述了JS截取与分割字符串的常用方法.分享给大家供大家参考,具体如下: JS截取字符串可使用 substring()或者slice() 函数:substring() 定义:substring( ...
- Xcode清楚缓存、清理多余证书路径
Xcode清除缓存.清理多余证书 1.删除Xcode中多余的证书provisioning profile 手动删除: Xcode6 provisioning profile path: ~/Libra ...
- Luogu网校听课笔记(自用
TG助学课——noilinux 8.2 深夜 Noi Linux的使用——darkflames的博客 #include<bits/stdc++.h> using namespace std ...
- Sublime Text 常用的16 个 Sublime Text 快捷键
在我做了一次包含一些现场编码的演示后,一些观众问我是如何操作这么快.当然这里没有唯一的答案,答案是一堆简单的快捷键和大量的实践的组合.为了回应那些询问,我觉得有必要看看我每天想都不用想且使用的快捷键. ...
- emacs版本差异(转载)
emacs23 就是原装的,由 gnu 发布的 emacs.emacs-lucid 是由 ubuntu 调整过的.emacs-nox 是不带 x system 的 emacs 版本.除非只在终端下用, ...
- C++语言中的static关键字的作用是什么?
在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变.在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量.在模块 ...
- Codeforces Round #408 (Div. 2) C.Bank Hacking(二分)
传送门 题意 给出n个银行,银行之间总共有n-1条边,定义i与j有边相连为neighboring,i到j,j到k有边,则定义i到k的关系为semi- neighboring, 每家银行hack的难度为 ...