Effective Objective C------ 1不要忘本

  Familiar your self with Objective-C 's root

Objective-C 与其它面向对象的语言相似,比方说C++, Java,但是在一些方面却不相同。如果你有过其它面向对象语言的编程经验,你会明白你所用的paradigms and patterns. 但是,由于OC使用了一个信息结构(messaging structure)而不是函数调用(function calling),因而语法会显得有些陌生。Objective-C从Smalltalk进化而来,Smalltalk是messaging structure的起源。 Messaging structure 与函数调用的不同之处如下所示:

//采用 Messaging 的Objective-C

//pseudo code

Object * obj=[Object new];

[obj performWith:parameter1 and:parameter2];


//在C++中

Object * obj=new Object;

obj->perform(parameter1,parameter2);

以上两个有什么不同呢?在Messaging Structure中,运行时(runtime)决定了哪些代码的运行。 然后在函数调用(function calling)中,是由编译器决定哪些代码去执行。 当多态(polymorphism)被引用到函数调用的例子中,运行时的检查表虚函数表。 但是在messaging structure过程中,总是在运行(runtime)时查找(look up)。实际上,编译器连被messaging的object都不关心。 这个object也将在runtime(运行时)被查找,采用的方式是dynamic binding(动态绑定)。这个将在item 11中详述。


// runtime

Objective-C的runtime component(运行时组件),做了大部分的工作;这些工作不是编译器做的。 运行时(runtime)包括了所有的数据结构和OC风格的函数。 例如:运行时(runtime)包括了所有的内存管理方法。 Essentially(根本上),runtime(运行时)包括了就是一些code,它们将你的所有的代码连接在一起,并且以一种动态库(dynamic library)的形式出现,这个动态库是你的代码要去连接的。因此,无论何时你的runtime被更新了,你的应用将会从性能提升中获益。一种编程语言,如果在编译时做更多工作的话就必须经过再编译(recompile)来获得性能的提高。 


Objective-C是一个C语言的一个扩展集,因此所有C语言的特性在Objective-C中都可以被使用。 因此,为了写出高效的Objective-C,你需要理解C语言与Objective-C语言的核 心概念。 尤其是,理解了C语言的内存模型将帮助你理解Objective-C语言的内存模型,你也会理解引用计数为啥是那样工作的。你要理解,一个指针被 用于表示一个Objective-C当中的对象(Object). 当你声明一个引用变量(指向一个对象),语法如下:

NSString * someString=@"The string";

这个语法,直接从C语言中而来,声明了一个叫做 someString的变量, 它的类型是NSString * . 这意味着someString是一个指向 NSString 的一人指针。 所有的Objective-C 对象都必须用这种方式声明,因为对象的内存总是在堆(heap)上开辟,从来不会在栈stack上面。如下声明一个objective-C对象是不合法的:

  NSString stackString;

这个叫做someString的变量,指向堆上的某块内存,这块内存中有一个NSString类型的对象。 这意味着创建另外一个变量指向同一位置的话不需要一份拷贝。两个变量可以指向同一个对象:

NSString * someString=@"The string";

NSString * anotherString=someString;

在这里,只有唯一的一个 NSString的实例,但是两个变量都指向相同的对象。 这两个变量都是 NSString * 的类型, 意味着当前的stack上面,会分配有2块空间,来装这两个变量,如果是32位的,就分配4个字节,如果是64位的,就分配,8个字节。(注:一个字节 8位)。 这两块memory中将包含相同的值: NSString实例的地址。


图1.1说明这种情形。 存储在NSString实例中的数据包括了那些要用来代表真正字符串的字节。


在堆(heap)上被分配的内存需要我们的直接管理,然而在栈上面的memory会被自动清除当这个被poped。

在堆(heap)上面的内存管理被Objective-C给抽象化了。你不需要用malloc ,free来分配或者摧毁对象的内存。 Objective-C的runtime将这个用引用计数给抽象出来。(具体见item 29)

有时,你将会遇到一些变量,它们并没有用*来声明,也许会用栈上面的空间。这些奕量并不是装用Objective-C的对象。 其中一个例子就是CGRect,它来自于CoreGraphics framework:

CGRect frame;

frame.origin.x=0.0f;

frame.origin.y=0.0f;

frame.size.width=100.0f;

frame.size.width=150.0f;


一个CGRect是一个C语言的结构体,如下定义:

struct CGRect{

CGPoint origin;

CGSize  size;

};

typedef struct CGRect CGRect ;

这种类型的结构体用在一些系统框架中,因为在这些框架中管理Objective-C对象会影响性能。 创建一个Objective-C对象,会导致一些管理(比如说分配或摧毁堆上内存),而使用结构体就不会。 当使用非对象时(int,float,double,char,等等)是要被装入的唯一的东西时,结构体会被用上。 比方说:CGRect.

在开始写Objective-C之前,我建议大家去阅读一些关于C语言的书籍,熟悉C语言的语法。如果一上来就搞Objective-C,你也许会发现一些语法confusing. 

您要记住的:

**** Objective-C是C语言的一个扩展集,增加了面向对象的特征。Objective-C使用了messaging structure,并且用了动态绑定。一个对象是在runtime时,被发现的。 是runtime的时候,决定了哪些代码去运行,而不是编译器。

**** 理解了C的核心概念将帮你写出高效的Objective-C。尤其要理解内存模型与指针。

另一个文章简单总结这一块。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值