了解Objective-C语言的起源
这里的东西都是我看书的心得体会,我尽量做到篇幅简短,内容易读(跟我们编代码的追求是一样的~~)
Objective-C 是面向对象语言,这个我认为大家都是明白的,但是他又与java、C++某些部分不一样
因为Objective-C使用的是“消息结构(messaging structure)”而不是像java等使用的时“函数调用(function calling)”
Objective-C是从 Smalltalk(点击查看相关内容) 演化而来,后者是消息型语言的鼻祖,他们的差别如下:
//messaging structure (Objective-C)
Object *obj = [[Object alloc] init];
[obj performWith:parameter1 and:parameter2];
//Function Calling (c++)
Object *obj = new Object;
obj -> perform(parameter1,parameter2);
消息结构和函数调用的差别中还有一个比较重要的(我认为比较重要),如果上面的代码中所使用的方法(函数)是多态的,那么:
函数调用的时候决定到底使用哪一个函数要按照“虚方法表”来查出到底应该执行哪一个函数来实现;
而消息结构则不需要管这个,他总是在运行的时候才会去查找索要执行的方法。
再说的多一些,消息结构在最开始的时候也不需要知道消息结构所要传的对象是什么类型的,他也会在运行是再处理。
Objective-C是C语言的“超集”,因此掌握C语言和Objective-C方能编写出高效的Objective-C代码。
Objective-C使用了“引用计数”的工作原理,这需要你了解C语言的指针
因为Obejctive-C创建一个对象后是使用指针来指示对象的,声明一个变量可以这样:
NSString *stringOne = @"string";
他定义了一个类型为NSString的变量,但是tringOne其实是一个指向NSString的指针,所有的Objective-C的对象都是这样声明和存储的
最终,我们存储的数据data("string")是放在内存堆中的,我们的指针则是放在栈中的。
如果我们再这样:
NSString *stringTwo = stringOne;
这不会让内存堆中多一个地方来存储data,只会在栈中增加一个指向这个data的指针和stringOne指向同一块内存,如下图
分配在堆中的内存必须直接处理,但是分配在栈顶的内存会在其弹出栈的时候自动清理。
引用计数就是针对这个特性来实现的。
但是在Objective-C中,有时候我们会遇到定义里不含*的变量,他们可能会使用“栈空间”。这些变量保存的不是Objective-C的对象。
例如CGRect。
CGRect frame;
frame.origin.x = 0.0f;
frame.origin.y = 10.0f;
frame.size.width = 100.0f;
frame.size.height = 100.0f;
CGRect 是 C 的结构体,其定义是:
struct CGRect{
CGPoint originl;
CGSize size;
};
typedef struct CGRect CGRect;
整个系统框架都会用到结构体这东西,如果每一个都存成一个对象的话,性能会受很大的影响,因此直接使用C语言是最好的选择。
如果只存储int、float、double、char等“非对象类型”,那么通常使用这种结构体就可以了。
虽然这是iOS高级开发技巧,很多人可能会觉得这一部分讲的这东西太基础了,根本不像高级开发啊。
可是仔细想想,在最开始的工作阶段,你是否被内存管理这样的东西弄的头疼脑热呢?
你可知道多少程序员在编程2年以上都搞不明白内存管理这个事情?
做编程就要打破砂锅问到底,如果我们不能清楚明白的搞懂objective-c是怎么样一个运作过程,那我们如何灵活的运用他呢?
在做objective-C开发之前,我强烈建议各位县看看C语言的教程,否则objective-C中的某些语法会让你困惑的。
要点
··· Objective-C 为 C 语言的超集,添加了面向对象特性。Objective-C使用消息结构,因此只有在运行的时候才会检查对象类型。接收一条消息之后,究竟应该执行何种代码,由运营期环境而非编译器来决定。
··· 理解C语言的核心概念有助于写好Objective-C程序。尤其是内存模型和指针。