最近在读一本effecttive Objective-C 2.0 ---- 编写高质量iOS与OS X代码的52个有效方法
笔者在这里记录一些比较好用的方法和技巧,如有错误或者疏漏,欢迎大家指正.
1. 首先简单介绍一下Objectice-C这门语言.
Objective-C通过一套全新的语法, 在C语言基础上添加了面向对象特性,Objective-C的语法中频繁使用方括号,而且不吝啬写出极长的名字,这通常令许多人觉得此语言比较冗长,其实这样写出来的代码十分易读,只是C++或许Java程序员不太适应.
2. 该语言使用消息结构(messaging structure) 而非函数调用(function calling).Object-C语言由Smalltalk演化而来,后者是消息型语言的鼻祖.消息与函数调用之间的区别看上去就像这样:
// Messaging (Objective-C) Object *obj = [Object new]; [obj performWith: parameter1 and: parameter2]; // Function calling (C++) Object *obj = [Object new]; obj->perform(parameter1, parameter2);</span>
3. Object-C的重要工作都是由"运行期组件"而非编译器完成的.使用Objective-C的面向对象特性所需的全部数据结构及函数都是在运行期组件里面.举例来说, 运行期组件中含有全部的内存管理方法.运行期组件本质上就是一种与开发者所编写代码相链接的动态库,其代码能把开发者编写的所有程序结合起来.
4.Object-C是C的超集, 所以C语言中的所有功能在编写OC代码时依然适用.因此必须同时掌握OC与C的核心概念,才能写出高效的OC代码,尤其重要的是C语言的内存模型,这有助于理解OC的内存模型以及引用计数机制的工作原理,同时要明白OC语言中的指针是用来指示对象的,
NSString *someString = @"The string";这种语法基本上就是照搬C语言的,声明了一个名为someString的变量,类型是NSString类型,此变量为指向NSString的指针.所有的OC语言的对象都必须这样声明,因为对象所占内存总是分配在堆空间中,而绝对不会分配在栈区,不能在栈上分配OC对象:
NSString stackString;
分配在堆中的内存必须管理,而分配在栈上用于保存变量的内存会在其栈帧弹出时自动清理.OC将堆内存管理抽象出来,不需要malloc及free来分配或者释放对象所占内存.OC运行期环境把这部分工作抽象在一套内存管理框架,名叫引用计数.
在OC代码中,有不包含*的变量, 它们可能会使用栈空间.这些变量所保存的不是OC对象, 比如CoreGraphics框架中的CGRect的例子: (CGRect 是 C结构体)
<span style="font-size:18px;"> // CGRect 变量 CGRect frame; frame.origin.x = 0.0f; frame.origin.y = 10.0f; frame.size.height = 100.f; frame.size.width = 150.0f; </span>整个系统框架都是在使用这种结构体,因为如果改用OC对象来做的话,性能会受到影响,与创建结构体相比, 创建对象还需要额外的开销.例如分配及释放堆内存等,如果需要保存非对象类型 int float char 等类型,那么通常使用CGRect这种结构体就可以了.
笔者建议: 如果新手编写OC代码的话, 最好先熟悉下C语言的语法, 这会让你解除一些困惑.
总结: OC为C语言添加了面向对象的特性, 尤其是超集. OC使用动态绑定的消息结构, 也就是说, 在运行时才会检查对象类型, 接受一条消息之后, 执行什么代码,由运行环境而非编译器来决定, 理解好C语言的核心概念有助于写好OC程序(内存模型和指针)