object-c

object-c

Object-C通常寫作Objective-C或者Obj-C或OC,是根據C語言所衍生出來的語言,繼承了C語言的特性,是擴充C的面向對象程式語言。它主要使用於Mac OS X和GNUstep這兩個使用OpenStep標準的系統,而在NeXTSTEP和OpenStep中它更是基本語言。Objective-C可以在gcc運作的系統寫和編譯,因為gcc含Objective-C的編譯器。在MAC OS X系統下,運用蘋果提供的SDK等開發工具包,可以用來做IOS開發,開發後的程式在Iphone虛擬機中進行測試,運用的主要語言為Object-c。與C#類似。Object-c僅支持單一父類繼承,不支持多重繼承。

基本介紹

  • 中文名:Objective-C
  • 別稱:Objective-C
  • 發明:布萊德·確斯
  • 公司:Stepstone
發展歷史,優點及缺點,和C++的比較,擴展的關鍵字,@interface,@implementation,new、alloc,@class,@property,@synthesize,記憶體管理,類別,@protocol,

發展歷史

二十世紀80年代初布萊德·確斯(Brad Cox)在其公司Stepstone發明Objective-C。他對軟體設計和編程里的真實可用度問題十分關心。 Objective-C最主要的描述是他1986年出版的Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8.

優點及缺點

Objective-C是非常“實際”的語言。它使用一個用C寫成、很小的運行庫,只會令應用程式的大小增加很小,和大部分OO系統使用極大的VM執行時間會取代了整個系統的運作相反,ObjC寫成的程式通常不會比其原始碼大很多。而其庫函式(通常沒附在軟體發行本)亦和Smalltalk系統要使用極大的記憶體來開啟一個視窗的情況相反。 Objective-C的最初版本並不支持垃圾回收。在當時這是爭論的焦點之一,很多人考慮到Smalltalk回收時有漫長的“死亡時間”,令整個系統失去作用。Objective-C為避免此問題才不擁有這個功能。雖然某些第三方版本已加入這個功能(尤是GNUstep),Apple在其Mac OS X 10.3中仍未引入這個功能。 另一個問題是ObjC不包括命名空間機制(namespace mechanism)。取而代之的是程式設計師必須在其類別名稱加上前綴,時常引致衝突。在2004年,在Cocoa編程環境中,所有Mac OS X類別和函式均有“NS”作為前綴,例如NSObject或NSButton來清楚分辨它們屬於Mac OS X核心;使用“NS”是由於這些類別的名稱在NeXTSTEP開發時定下。 雖然Objective-C是C的母集,但它也不視C的基本型別為第一級的對象。 和C++不同,Objective-C不支持運運算元重載(它不支持ad-hoc多型)。亦與C++不同,但和Java相同,Objective-C只容許對象繼承一個類(不設多重繼承)。Categories和protocols不但可以提供很多多重繼承的好處,而且沒有很多缺點,例如額外執行時間過重和二進制不兼容。

和C++的比較

  1. 目前好象只有Apple使用Objective-C作為其支持的語言吧。
  2. 與C++的不同之處有:
  3. OC中所有的類都必須繼承自NSObject。
  4. OC中所有對象都是指針的形式。
  5. OC用self代替this。
  6. OC使用id代替void*。
  7. OC使用nil表示NULL
  8. OC只支持單繼承。
  9. OC使用YES/NO表示TRUE/FALSE
  10. OC使用#import代替#include
  11. OC中用訊息表示類的方法,並採用[aInstance method:argv]調用形式。
  12. OC支持反射機制
  13. OC支持Dynamic Typing, Dynamic Binding和Dynamic Loading。
  14. 與C++的相同之處有:
  15. 與C共享的部分一致。
  16. 可以使用assert(BOOL), 一般用NSCParameterAssert(BOOL)代替。
  17. OC中的命名前綴說明:
  18. NS-:NextStep
  19. CF-:Core Foundation
  20. CA-:Core Animation
  21. CG-:Core Graphics
  22. UI-:User Interface
  23. OC中的訊息特殊性:
  24. 調用訊息的類可以不知道如何回響這個訊息。如果它不知道如何處理這個訊息,它會自動的將這個訊息轉給其他的類,比如它的父類。
  25. 調用訊息的類可以是nil。在C++中,在使用類方法之前,我們都需要檢查對象是否為空,所以在實現析構函式的時候,常會有如下的代碼,如if (var) { delete var; }但是在objective c中,我們就可以直接寫[var release];即使var == nil, 也不會有問題。
  26. OC中的函式聲明格式有:
  27. -/+ (return type) function_name;
  28. -/+ (return type) function_name : (parameter type) parameter;
  29. -/+ (return type) function_name : (parameter type) parameter1otherParameter: (parameter_type) parameter2
  30. 以上參數說明:-表示一般函式,+表示靜態函式。otherParameter是參數的別名(第一個參數的別名省略),在函式調用時方便指定。
  31. OC中的構造/析構函式
  32. OC中的init()/release()對應於C++的構造/析構函式。alloc()/dealloc()也就對應於C++的new和delete,其中的dealloc()由於引用計數的自動調用而不用手動調用。
  33. OC中父類的init()/release()函式需要子類的手動調用。而且每次都必須調用。不同於C++的自動調用。
  34. 構造函式(- (id) init)調用形如:CSample* pSample=[CSample alloc] init];其中alloc(+ (id) alloc)是繼承來的static函式,init是繼承來的一般函式,如重寫一般函式時,則相當於C++的覆蓋(不帶參數)或重載(帶參數)。
  35. 析構函式(- (void) release)將引用計數減1,當=0時父類的release()會自動調用dealloc(- (void) dealloc);
  36. 當OC沒有數據成員時,可省略{},建議保留。
  37. 繼承下來的方法,如:-(id) init可以頭檔案中省略,建議保留
  38. OC中只有數據成員的訪問限制,沒有方法的訪問限制。
  39. 同C++一樣,數據成員有三種訪問限制public, protected, private,預設是protected。
  40. 示例:@interface AccessExample: NSObject {
    @public
    int publicVar;
    @protected
    int protectedVar;
    @private
    int privateVar;
    }
    @end
  41. 方法的訪問限制可通過Category實現
  42. 示例:
    @interface MyClass
    - (void) sayHello {
    NSLog(@"Hello");

    }

    @end



    @interface MyClass(Private)
    - (void) kissGoodbye;
    @end
  43. OC中沒有類的靜態變數,只有全局變數
  44. OC中的數組NSArray可以保存不同對象類型的數據。
  45. OC也支持runtime時的類型檢查
  46. - (BOOL) isKindOfClass: classObj
    用於判斷該對象是否屬於某個類或者它的子類
  47. - (BOOL) isMemberOfClass: classObj
    用於判斷該對象是否屬於某個類(這裡不包括子類)
  48. - (BOOL) respondsToSelector: selector
    用於判斷該對象是否能回響某個訊息。這裡,我們可以將@selector後面帶的參數理解為C++中的函式指針。
    注意:1)不要忘了@ ;2)@selector後面用的是(),而不是[ ] ;3)要在訊息名稱後面跟:,無論這個訊息是否帶參數。如:[pSquare respondsToSelector:@selector(Set: andHeight:)]。
  49. + (BOOL) instancesRespondToSelector: selector
    用於判斷該類是否能回響某個訊息。這是一個靜態函式。
  50. -(id) performSelector: selector :調用對象的selector方法。
  51. conformsToProtocol 類似於respondsToSelector ,用於動態檢查某個對象是否遵守某個協定。
  52. Category:在沒有原始碼的情況下,為一個已經存在的類添加一些新的功能
  53. 只能添加新的方法,不能添加新的數據成員
  54. Category的名字必須是唯一的
  55. Protocol:相當於C++中的純虛類
  56. 形如:@interface MyDate: NSObject <Printing> { } @end
  57. 使用:MyDate * dat = [[MyDate alloc] init];id<Printing> var = dat; [var print]。
  58. 說明:我們首先聲明了Printing 協定,任何遵守這個協定的類,都必須實現print 方法。在Objective C 中,我們通過<>來表示遵守某個協定。當某個類聲明要遵守某個協定之後,它就必須在.m檔案中實現這個協定中的所有方法。使用id<Printing> 作為類型,而不是象C++中的Printing* var。
  59. IBOutlet, IBAction: 這兩個東西其實在語法中沒有太大的作用。如果你希望在Interface Builder中能看到這個控制項對象,那么在定義的時候前面加上IBOutlet,在IB里就能看到這個對象的outlet,如果你希望在Interface Builder里控制某個對象執行某些動作,就在方法前面加上(IBAction)。
  60. 儘量避免在一行語句中進行兩層以上的嵌套
  61. 訊息轉發:- (void) forwardInvocation: (NSInvocation*)anInvocation;

擴展的關鍵字

@interface

類型聲明,類似於c++中的class,區別在於Object c中的聲明與實現是強制分開的,@interface關鍵字用於類型的聲明,包括數據成員、方法聲明、屬性等。方法的參數傳遞採用中綴符的形式,利用“:”分割參數名和被傳遞參數,類型的聲明以@interface開頭,以@end結束,通常一個類型的聲明採用下面的結構:
@class someOtherObject //外部類型聲明
@interfacesomeObject:NSObject //繼承的類型
{
int i; //成員變數
}
-(id)someMethod:(int)someArg someOtherArgName:(int)someOtherArg; //對象的方法
+(id)someMethod:(int)someArg; //類方法
-(id)init; //初始化方法
@propertyint num; //屬性
@end

@implementation

對應於@interface的類型聲明,@implementation表示一個類型的實現過程,同樣以@end結束,實現的格式通常如下:
@implementationsomeObject
-(id)someMethod:(int)someArg someOtherArgName:(int)someOtherArg
{
//實現代碼
}
@synthesize num=i; //將屬性與變數進行對應
@end

new、alloc

Object C中的方法調用形式採用訊息傳送的方式,通常調用的形式如
[someObject someMethod:firstArg someOtherArgName:otherArg]
實例的初始化也採用訊息傳送的形式,可以簡單的調用類型的new方法來獲取一個實例對象,簡單實例化的方法通常是:
someObject *obj = [someObjectnew]; //類的實例化
new方法的實際過程是調用allocinit方法,因此如果需要採用自定義的方法來初始化實例,則需要自己重寫init方法,通常的初始化方式為:
someObject *obj = [[someObject alloc] init]; //採用無參數的init實例化
someObject *obj = [[someObject alloc] initWithArg:Arg]; //採用參數的實例化

@class

@class是一個前向引用聲明,類似於C++中的friend友元聲明,其作用是告訴編譯器其後面的欄位代表一個類型名稱,儘管不知道類型的具體實現,但是只需要將其作為一個類型名稱處理即可。通常在使用複合的結構時可以採用@class來減少頭檔案的相互引用,如果出現循環依賴,則需要依靠@class來避免引用的死循環。通常使用形式為:
@classsomeOtherObject;
@interfacesomeObject:NSObject
{
someOtherObject *obj;
}
@end

@property

儘管可以使用obj->arr的形式去強制讀取對象的成員變數,但是良好的編程形式是對外界提供成員變數的讀寫接口。@property關鍵字提供了外界對成員變數的訪問接口,其本質是為某一個屬性提供set和get操作。根據不同的需要,可以添加readonly(唯讀,相當於只添加get不添加set方法)或者readwrite(讀寫,如果不添加則為默認);還有三種賦值方式可選:assign(直接賦值,通常用於基本類型),retain(釋放舊值,增加新的retaincount),copy(常用於字元串,生成一個新的拷貝)。通常使用的方式如下:
@interface someObject:NSObject
{
int i; //成員變數
}
@property (assign,readonly) int num; //屬性
@end

@synthesize

@property對應,將一個外在屬性與成員變數相關聯,定義在@implementation中,如果屬性名與變數名一致則可以省略變數名。常用方法:
@implementation someObject
@synthesize num=i;//如果屬性名也為i,則可以直接寫為 @synthesizei
@end

記憶體管理

Object C採用引用計數的方式進行記憶體管理,由於所有的對象都繼承於NSObject,因此所有的對象都可以接受NSObject的三個方法:
-(id)retain;
-(void)release;
-(unsigned)retainCount;
retain方法將對象的引用計數加一併返回該對象,release將引用計數減一,retainCount方法返回對象當前的引用計數。當採用new、alloc、copy方法創建一個對象時,它的引用計數被置為1,如果程式中對該對象進行操作,則應根據需要,通過調用retain和release方法來保證該對象在不需要的時候被清除。當一個對象的引用計數被置為0後,系統會自動向對象傳送一個dealloc訊息,將其占有的資源釋放。通常情況下,如果一個對象的初始化過程調用了其他資源,則應該重寫改對象的dealloc過程,保證在對象的銷毀期正確釋放這些資源。
為了更加方便的進行能存管理,cocoa中提供了一個自動釋放池(autorelease pool)的概念,每一個類都繼承了一個autorelease方法,當調用對象的autorelease方法時,改對象會被加入到開始創建的自動釋放池中。當程式進行到不再需要自動釋放池中的對象時,將自動釋放池釋放的時候會向池中的所有對象傳送一個release訊息,從而保證不再需要的對象被正確的釋放。通常的用法如下:
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
someObject * obj = [[someObject alloc] init];
[obj autorelease]; //加入自動釋放池
//其他代碼
[pool release]; //執行該語句時,系統會向池內所有的對象傳送release訊息;在這個例子中,如果對obj進行的其他retain操作和release操作保持一致的話,則會將obj的引用計數變為0,從而調用它的dealloc方法進行資源釋放
Object C進行記憶體管理的3條規則是:
  1. 如果使用new、alloc或copy操作獲得一個對象,則該對象的保留計數器值為1
  2. 如果通過任何其他方法獲得一個對象,則假設該對象的保留計數器值為1,而且已經被設定為自動釋放
  3. 如果保留了某個對象,則必須保持retain方法和release方法的使用次數相等。

類別

類別是為現有的類提供一個新的方法的方法,即使沒有一個類的原始碼,仍然可以向類中添加一個方法以方便使用。類別的主要目的有3個:將類的實現分散到多個不同的檔案或框架中,創建對私有方法的前向引用,向對象添加非正式協定。
類別的聲明方法:
@interfacesomeObject (someProtocal)
-(void)someMethod;
@end
類別的實現方法:
@implementationsomeObject(someProtocal)
-(void)someMethod
{
}
@end

@protocol

Object C中的協定類似於java中的接口,通過@protocol關鍵字定義一個或多個需要遵從協定的對象實現的方法,協定定義的方法:
@protocolsomeProtocol
-(void)someMethod;
@end
採用協定的方法是在類聲明時使用尖括弧註明其需要使用的協定:
@interfacesomeObject:NSObject <someProtocol>
在類實現時需要將協定中規定的方法都予以實現。
Object C 2.0增加了2個新的協定修飾符@optional@required,可以規定協定中的方法是否為必須實現的方法。

相關詞條

熱門詞條

聯絡我們