1. 程式人生 > >O-C和C的差別以及其自身的特點

O-C和C的差別以及其自身的特點

Objective-C中有幾種資料型別和C不太一樣:

  • - id 是一個指標型別,可以指向任何型別的物件
  • - BOOL和char是一樣的,但是做為布林值使用。
  • YES 表示1
    NO 表示0

  • - IBOutlet 是個沒有任何意義的巨集,可以忽略。當InterfaceBuilder從.h檔案中讀取類定義時,這個巨集會對其做出一個提示。
  • - IBAction和void是一樣的,同樣僅用作對Interface Builder的提示。
  • - nil和NULL是一樣的,我們使用nil而不用NULL是因為我們用來表示物件的指標為空。

另外
#import和#include是一樣的,但是#import可以確保引用的檔案只被引用一次。

四月 18, 2011
  1. 目前好象只有Apple使用Objective-C作為其支援的語言吧。
  2. 與C++的不同之處有:
    • O-C中所有的類都必須繼承自NSObject。
    • O-C中所有物件都是指標的形式。
    • O-C用self代替this。
    • O-C使用id代替void*。
    • O-C使用nil表示NULL
    • O-Ck只支援單繼承。
    • O-C使用YES/NO表示TRUE/FALSE
    • O-C使用#import代替#include
    • O-C中用訊息表示類的方法,並採用[aInstance method:argv]呼叫形式。
    • O-C支援反射機制
    • O-C支援Dynamic Typing, Dynamic Binding和Dynamic Loading。
  3. 與C++的相同之處有:
    • 與C共享的部分一致。
    • 可以使用assert(BOOL), 一般用NSCParameterAssert(BOOL)代替。
  4. O-C中的命名字首說明:
    • NS-:NextStep
    • CF-:Core Foundation
    • CA-:Core Animation
    • CG-:Core Graphics
    • UI-:User Interface
  5. O-C中的訊息特殊性:
    • 呼叫訊息的類可以不知道如何響應這個訊息。如果它不知道如何處理這個訊息,它會自動的將這個訊息轉給其他的類,比如它的父類。
    • 呼叫訊息的類可以是nil。在C++中,在使用類方法之前,我們都需要檢查物件是否為空,所以在實現解構函式的時候,常會有如下的程式碼,如if(var) { delete var; }
      但是在objective c中,我們就可以直接寫[varrelease]; 即使var == nil, 也不會有問題。
  6. O-C中的函式宣告格式有:
    • -/+ (return type) function_name;
    • -/+ (return type) function_name : (parameter type)parameter;
    • -/+ (return type) function_name : (parameter type)parameter1 otherParameter :(parameter_type) parameter2
    • 以上引數說明:-表示一般函式,+表示靜態函式。otherParameter是引數的別名(第一個引數的別名省略),在函式呼叫時方便指定。
  7. O-C中的構造/解構函式
    • O-C中的init()/release()對應於C++的構造/解構函式。alloc()/dealloc()也就對應於C++的new和delete,其中的dealloc()由於引用計數的自動呼叫而不用手動呼叫。
    • O-C中父類的init()/release()函式需要子類的手動呼叫。而且每次都必須呼叫。不同於C++的自動呼叫。
    • 建構函式(- (id) init)呼叫形如:CSample* pSample=[CSample alloc]init];其中alloc(+ (id)alloc)是繼承來的static函式,init是繼承來的一般函式,如重寫一般函式時,則相當於C++的覆蓋(不帶引數)或過載(帶引數)。
    • 解構函式(- (void) release)將引用計數減1,當=0時父類的release()會自動呼叫dealloc(-(void) dealloc);
  8. 當O-C沒有資料成員時,可省略{},建議保留。
  9. 繼承下來的方法,如:-(id) init可以標頭檔案中省略,建議保留
  10. 0-C中只有資料成員的訪問限制,沒有方法的訪問限制。
    • 同C++一樣,資料成員有三種訪問限制public, protected,private,預設是protected。
      示例:
      1 2 3 4 5 6 7 8 9 @interface AccessExample: NSObject { @public intpublicVar; @protected intprotectedVar; @private intprivateVar; } @end
    • 方法的訪問限制可通過Category實現
      示例:
      1 2 3 4 5 6 7 8 9 @interface MyClass -(void) sayHello { NSLog(@"Hello"); } @end @interface MyClass(Private) -(void) kissGoodbye; @end
  11. O-C中沒有類的靜態變數,只有全域性變數
  12. O-C中的陣列NSArray可以儲存不同型別的資料。
  13. O-C也支援run-time時的類型別檢查
    • - (BOOL) isKindOfClass: classObj
      用於判斷該物件是否屬於某個類或者它的子類
    • - (BOOL) isMemberOfClass: classObj
      用於判斷該物件是否屬於某個類(這裡不包括子類)
    • - (BOOL) respondsToSelector: selector
      用於判斷該物件是否能響應某個訊息。這裡,我們可以將@selector後面帶的引數理解為C++中的函式指標。
      注意:
      1)不要忘了@
      2)@selector後面用的是(),而不是[]。
      3)要在訊息名稱後面跟:,無論這個訊息是否帶引數。如:[pSquarerespondsToSelector:@selector(Set: andHeight:)]。
    • + (BOOL) instancesRespondToSelector: selector
      用於判斷該類是否能響應某個訊息。這是一個靜態函式。
    • -(id) performSelector: selector :呼叫物件的selector方法。
    • conformsToProtocol 類似於respondsToSelector,用於動態檢查某個物件是否遵守某個協議。
  14. Category:在沒有原始碼的情況下,為一個已經存在的類新增一些新的功能
    • 只能新增新的方法,不能新增新的資料成員
    • Category 的名字必須是唯一的
  15. Protocol:相當於C++中的純虛類
    • 形如:@interface MyDate: NSObject<Printing> { } @end
    • 使用:MyDate * dat = [[MyDate alloc] init];id<Printing> var = dat; [varprint]。
    • 說明:我們首先聲明瞭Printing 協議,任何遵守這個協議的類,都必須實現print 方法。在Objective C中,我們通過<>來表示遵守某個協議。當某個類宣告要遵守某個協議之後,它就必須在.m檔案中實現這個協議中的所有方法。使用id<Printing> 作為型別,而不是象C++中的Printing*var。
  16. IBOutlet, IBAction: 這兩個東西其實在語法中沒有太大的作用。如果你希望在InterfaceBuilder中能看到這個控制元件物件,那麼在定義的時候前面加上IBOutlet,在IB裡就能看到這個物件的outlet,如果你希望在Interface Builder裡控制某個物件執行某些動作,就在方法前面加上(IBAction)。
  17. 儘量避免在一行語句中進行兩層以上的巢狀
  18. 訊息轉發:- (void) forwardInvocation:(NSInvocation*)anInvocation;
四月 18, 2011

Categories

1 2 3 4 5 6 7 8 #import “ClassName.h” @interface ClassName ( CategoryName ) //method declarations @end #import “ClassName+CategoryName.h” @implementation ClassName ( CategoryName) //method definitions @end

For example

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @interface MyObject : NSObject{ NSNumber *number; } -(NSNumber *)number; @end @interface MyObject (Setter) -(void)setNumber:(NSNumber *)newNumber; @end @implementation MyObject -(NSNumber *)number{ return number; } -(void)setNumber(NSNumber *)newNumber{ number = newNumber; } @end

Protocol

1 2 3 4 5 6 7 8 @protocol MyProtocol -(void)requiredMethod; @optional -(void)anOptionalMethod; -(void)anotherOptionalMethod; @required -(void)anotherRequiredMethod; @end

For example

1 2 3 4 5 6 7 8 9 10 Inherit multiple protocol. @interface Formatter :NSObject Instance. Protocol *myXMLSupportProtocol [email protected](MyXMLSupport); Check if methods are declared if(![receiverconformsToProtocol:@protocol(MyXMLSupport)]){ //Object does not conform to MyXMLSupportprotocol //If you are expecting receiver to implement methodsdeclared in the //MyXMLSupport protocol, this is probably anerror } -(NSString*)formattingService:(id)anObject; ———————————————————————

http://icocoa.cn/ocsection/oc-tips/60-category-vs-protocol

Category
Category提供了一種比繼承(inheritance)更為簡潔的方法來對class進行擴充套件,我們可以為任何已經存在的class新增方法(不包括資料成員)卻不需要訪問該class的實現檔案。
新新增的方法和原有的方法具有同等的地位,可以訪問class的資料成員,並且完全植入到class的繼承體系之中,子類同樣會繼承新新增的方法。利用category對類進行擴充套件可以避免使類的繼承體系過於臃腫,複雜,降低了維護成本。另外,新新增的方法如果和已經存在的方法具有相同的prototype,那麼新新增的方法將會覆蓋已經存在的方法,也就是category使得使得在沒有原始檔時修改已存在class的functionality或者清除bug成為可能,所有該class的物件的行為都將發生變化,這一點是繼承無法達到的。

Category的缺點:
如果一個已經存在的方法被新方法覆蓋,那麼將沒有任何途徑可以對舊方法進行呼叫。這一點和繼承是不同的,子類對父類成員函式重寫(override),但我們依然可以對父類中的被重寫的成員函式進行呼叫。
如果有多個category對同一個class的成員函式進行重寫,那麼具體的行為是未定義。
Category的應用:
對類進行擴充套件或patch。
使用category或(anonymous category)來模擬實現private method。
使用category(informal protocol)來實現delegation,在cocoaframework中就大量使用了category來宣告delegate methods。
利用category把一個龐大的class劃分為小塊兒來分別進行開發,從而將functionality更好的進行劃分,利於維護。