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 |
Objective-C FAQ 中文版(轉貼)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.