Objective-C FAQ 中文版(转贴)

Objective-C FAQ

编辑:David Stes ( [email protected])
发表:2003年1月28日
翻译者:jeff_yecn


目录

* 目录
* 1. 关于本FAQ
+ 1.1 我在哪里可以找到本FAQ的最新版本?
* 2. Objective-C 编译器指令
+ 2.1 Objective-C 源程序的文件后缀是什么?
+ 2.2 我怎么用Stepstone编译器编译.m文件?
+ 2.3 我怎么用苹果编译器编译.m文件?
+ 2.4 我怎么用GNU C编译器编译.m文件?
+ 2.5 我怎么用POC编译器编译.m文件?
* 3. Objective-C 预处理器问题
+ 3.1 注释语句的语法是什么?
+ 3.2 我怎么包含根类
+ 3.3 什么是#import
+ 3.4 为什么要教我使用#import?
* 4. 对象的数据类型(id)
+ 4.1 什么是id
+ 4.2 self和super有什么不同?
+ 4.3 什么是@defs( )?
* 5 消息选择器(SEL)
+ 5.1 什么是SEL?
+ 5.2 perform: 有什么用处?
+ 5.3 我怎么知道给定method的SEL?
* 6. 实现指针(IMP)
+ 6.1 什么是IMP?
+ 6.2 怎么通过给定的SEL获得IMP?
+ 6.3 怎么通过给定的IMP发送消息?
+ 6.4 怎么将IMP用于要返回双精度浮点数的method?
+ 6.5 对一个返回双精度浮点数的method,可以用perform: 吗?
* 7. 复制对象
+ 7.1 copy和deepcopy有什么区别?
* 8. Objective-C和C++
+ 8.1 怎么把一个C++库连接到Objective-C程序中?
* 9. 消息
+ 9.1 我怎么产生一个静态的method?
+ 9.2 我怎么阻止一个对象发送某个消息?
+ 9.3 如果我更改了一个method的实现,怎么对所有代码进行重新编译?
* 10. 实例和类变量
+ 10.1 如果我对一个类的实例变量进行了改变的话,我需要对所有代码进行重新编译吗?
* 11. Objective-C和X-Windows
+ 11.1 我怎么把X Intrinsic头文件包含到Objective-C文件中?
* 12. Stepstone专有问题
+ 12.1 我怎么在栈中分配对象?
* 13. GNU Objective-C专有问题
+ 13.1 为什么我会得到一个“浮点例外”错误?
* 14. 苹果Objective-C专有问题
+ 14.1 什么是字符串常量的类?
+ 14.2 我怎么把C++库与Objective-C程序连接?
* 15. 可移植对象编译器(POC)专有问题
+ 15.1 类变量的语法是什么?
+ 15.2 怎么转发消息?
+ 15.3 我怎么把C++库与Objective-C程序连接?
* 16. 书籍和进一步阅读材料
+ 16.1 Object-Oriented Programming : An Evolutionary Approach, 2nd Ed.
+ 16.2 An Introduction To Object-Oriented Programming, 2nd Ed.
+ 16.3 Objective-C : Object-Oriented Programming Techniques
+ 16.4 Applications of Object-Oriented Programming; C++ SmallTalk Actor Objective-C Object PASCAL

1. 关于本FAQ

1.1 我在哪里可以找到本FAQ的最新版本?
它每月会在comp.lang.objective-c,comp.answers和news.answers。
同时会归档在ftp://rtfm.mit.edu/pub/faqs/computer-lang/Objective-C/faq。

2. Objective-C 编译器指令

2.1 Objective-C 源程序的文件后缀是什么?
实施文件(implementation file)的后缀是.m,头文件的后缀是.h。Objective-C编译器通常也接受.c作为后缀,但是仅把这些文件按照普通C语言的模式进行编译。

2.2 我怎么用Stepstone编译器编译.m文件?
objcc -c class.m
objcc -o class class.o
详细信息请参见http://www.stepstn.com

2.3 我怎么用苹果编译器编译.m文件?
cc -c class.m
cc -o class class.o
详细信息请参见http://www.apple.com

2.4 我怎么用GNU C编译器编译.m文件?
gcc -c class.m
gcc -o class class.o -lobjc -lpthread

2.5 我怎么用POC编译器编译.m文件?
objc -c class.m
objc -o class class.o -lobjc -lpthread

3. Objective-C 预处理器问题

3.1 注释语句的语法是什么?
Objective-C的预处理器通常支持两类注释:
// 这是BCPL风格的注释(有效到本行的末尾)

/* 这是C风格的注释 */

3.2 我怎么包含根类(include the root class)
对stepstone和POC,头文件可以这样包含:

对GNU cc和苹果cc,则:

对Stepstone编译器,根类位于一个叫做runtime的目录中,而对POC编译器,则位于一个叫objcrt的目录里。但由于隐含调用的-I参数传递了给预处理器,上述位置会被自动搜索。

3.3 什么是#import
这是一个C预处理指令,避免同一个文件被多次包含。
#import
相当于:
#include
如果这个.h文件能够用下面的办法保护自己避免被重复包含
#ifndef _OBJECT_H_
...
#define _OBJECT_H_
#endif

3.4 为什么要教我使用#import?
由于发现有些人用不好的风格来使用#import,GNU Objective-C编译器会在你使用#import时发送一个错误信息。你可以通过-Wno-import选项来关闭这个警告信息。你也可以通过修改编译器源代码,设置warn_import变量(在文件cccp.c)中。你也可以想上一个问题那样,把你的代码改为使用#ifndef和#endif对,使得你的代码可以运行在所有编译器上。

4. 对象的数据类型(id)

4.1 什么是id
它是Objective-C对各种对象使用的一个通用的C数据类型。例如,一个静态函数,参数为一个对象,返回值也是一个对象,可以这样声明:
static id myfunction(id argument) {...}

4.2 self和super有什么不同?
self是在method的实现中的一个变量,它表示接收消息的对象。super表示同样的变量,但要求编译器使用其超类(superclass,姑且这么翻译,指当前类所继承的一系列类)中的一个method实现。
如果使用伪码的话,假设copy (from super) 是调用超类中copy这个实现的语法,那么下面两条语句是等价的:
myObject = [super copy];

myObject = [self copy (from super)]; //伪码

4.3 什么是@defs( )?
这是一个编译器指令,作用是访问某一个类的实例的内部存储结构。
typedef struct { @defs(MyClass) } *TMyClass;
定义了一个叫TMyClass的C类型,它的存储结构与MyClass实例是完全一样的。




5 消息选择器(SEL)

5.1 什么是SEL?
这是消息选择器对应的C类型。它通常定义为唯一的字符串(method的名字,包括冒号)。但也并非所有的编译器都是这样定义的。

5.2 perform: 有什么用处?
perform: 是一个消息,它要求给一个对象发送一条由它的消息选择器(SEL)指定的消息。

5.3 我怎么知道给定method的SEL?
如果method的名字在编译时已经知道,使用@selector:
[myObject perform: @selector(close)];
如果是在运行时,你可以通过一个以消息名为参数的运行时函数获得消息选择器,例如:
SEL mySel = selUid(name); //对Stepstone编译器
SEL mySel = sel_getUid(name); //对苹果编译器
SEL mySel = sel_get_any_uid(name); //对GNU Objective-C编译器
SEL mySel = selUid(name); //对POC编译器

6. 实现指针(IMP)

6.1 什么是IMP?
它是method的实现指针的C类型。一个指向实现Objective-C的method的函数的指针。它被定义为返回id类型,并有两个隐含参数,self和_cmd:
typedef id (*IMP) (id self, SEL _cmd, ...);

6.2 怎么通过给定的SEL获得IMP?
可以通过发送一个methodFor: 消息完成:
IMP myImp = [myObject methodFor: mySel];

6.3 怎么通过给定的IMP发送消息?
通过重设函数指针。下面的语句是等价的:
[myObject myMessage];

IMP myImp = [myObject methodFor: @selector(myMessage)];
myImp(myObject, @selector(myMessage)];

[myObject perform: @selector(myMessage)];

6.4 怎么将IMP用于要返回双精度浮点数的method?
对返回值不是id而是象双精度浮点数这样的C类型的method,需要将IMP函数指针从返回id的函数强制转换成返回双精度浮点数的函数:
double aDouble = ((double (*) (id, SEL))myImp)(self, _cmd);

6.5 对一个返回双精度浮点数的method,可以用perform: 吗?
不行。perform: 这种method是用于发送不含其它参数的返回id类型的消息的。如果消息返回id类型,但有一个其它参数,使用perform: with: 。如果是任意参数数目和任意返回类型的普遍情况,使用methodFor: 。

7. 复制对象

7.1 copy和deepcopy有什么区别?
copy是对对象的字节拷贝,与原有对象共享指针,可以被重载以拷贝附加的内存。deepcopy是建立一个不共享指针的拷贝。一个对象的deepcopy包括它的实例变量的拷贝,而一般的复制则通常只包括第一层的拷贝。

8. Objective-C和C++

8.1 怎么把一个C++库连接到Objective-C程序中?
你可以有两个选择:使用苹果编译器或POC。前者接受C++和Objective-C的混合语法(称做Objective-C++)。后者把Objective-C代码先编译成C,在用C++编译器对中间代码进行编译。详细信息请参见编译器专有问题的解答。(译注:14,15章)

9. 消息

9.1 我怎么产生一个静态的method?
method在Objective-C中总是以静态函数的形式实现的。但获得一个method的IMP(实现指针)的唯一方法只能是通过运行时消息(通过methodFor: 和friends),因为对于实现method的文件来说,函数本身是静态的。

9.2 我怎么阻止一个对象发送某个消息?
你不可以。如果你的对象能够响应一个消息,那么其他类就可以发送这个消息。你可以增加一个额外的sender参数来进行检查,例如:
- mymethod: sender
{
if ([sender isKindOf: ...]) ...
}
但这仍然要求发送方使用正确的参数以进行配合:
[anObject mymethod: self];

9.3 如果我更改了一个method的实现,怎么对所有代码进行重新编译?
不,你仅需要对更改了代码的文件本身重新编译就可以了。仅仅是发送特定消息的文件是不需要重新编译的,因为Objective-C使用动态绑定。

10. 实例和类变量

10.1 如果我对一个类的实例变量进行了改变的话,我需要对所有代码进行重新编译吗?
你需要对那个类,和它的所有子类,和那些使用@defs或对那个类的实例变量进行直接访问的文件进行重新编译。简而言之,使用@defs来访问实例变量,或通过子类来访问实例变量,破坏了Objective-C通常提供给其他文件(那些你不需要重新编译的文件)的封装。

11. Objective-C和X-Windows

11.1 我怎么把X Intrinsic头文件包含到Objective-C文件中?
为避免Objective-C对象和X11对象的冲突,请参考下面的代码:
#include
#define Object XtObject
#include
#include
#undef Object

12. Stepstone专有问题

12.1 我怎么在栈中分配对象?
要在栈中分配“MyClass”的一个实例:
MyClass aClass = [MyClass new];

13. GNU Objective-C专有问题

13.1 为什么我会得到一个“浮点例外(floating point exception)”错误?
这常在某些平台上发生,并在ftp://ftp.ics.ele.tue.nl/pub/users/tiggr/objc/README.387中描述过。一个解决方案是在命令行添加-lieee参数,使得在运行时一个非法浮点操作不传送错误信息。DJGPP用户可以参考http://www.delorie.com/djgpp/v2faq/。AIX用户可以参考http://world.std.com/~gsk/oc-rs6000-problems.html。某些情况下,你也可以通过升级到更新版本的GNU Objective-C运行时库和/或编译器来解决这个问题。

14. 苹果Objective-C专有问题

14.1 什么是字符串常量的类?
它是NXConstantString。
NXConstantString *myString = @ "my string";

14.2 我怎么把C++库与Objective-C程序连接?
c++ -c file.m
c++ file.o -lcpluslib -o myprogram

15. 可移植对象编译器(POC, Portable Object Compiler)专有问题

15.1 类变量的语法是什么?
把类变量列在实例变量的后面,并和实例变量一样组织在一起,如下:
@implementation MyClass : Object { id ivar1; int ivar2; } : { id cvar1; }
@end

15.2 怎么转发消息?
应该通过实现doesNotUnderstand: 来发送sentTo: 消息。
- doesNotUnderstand : aMsg
{
return [aMsg sentTo: aProxy];
}

15.3 我怎么把C++库与Objective-C程序连接?
objc -c -cplus file.m
objc -cplus file.o -lcpluslib -o myprogram

16. 书籍和进一步阅读材料

16.1 Object-Oriented Programming : An Evolutionary Approach, 2nd Ed.
Brad Cox & Andy Novobilski, ISBN 0201548348.

16.2 An Introduction To Object-Oriented Programming, 2nd Ed.
Timothy Budd, ISBN 0201824191

16.3 Objective-C : Object-Oriented Programming Techniques
Pinson, Lewis J. / Wiener, Richard S., ISBN 0201508281

16.4 Applications of Object-Oriented Programming; C++ SmallTalk Actor Objective-C Object PASCAL
Pinson, Lewis J. / Wiener, Richard S., ISBN 0201503697

你可能感兴趣的:(iPhone开发)