發展歷史
二十世紀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++的比較
目前好象只有Apple使用Objective-C作為其支持的語言吧。
與C++的不同之處有:
1.目前好象只有Apple使用Objective-C作為其支持的語言吧。
2.與C++的不同之處有:
3.擴展的關鍵字
@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 = [someObject new]; //類的實例化
new方法的實際過程是調用 alloc和 init方法,因此如果需要採用自定義的方法來初始化實例,則需要自己重寫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條規則是:
如果使用new、alloc或copy操作獲得一個對象,則該對象的保留計數器值為1
如果通過任何其他方法獲得一個對象,則假設該對象的保留計數器值為1,而且已經被設定為自動釋放
如果保留了某個對象,則必須保持retain方法和release方法的使用次數相等。
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,可以規定協定中的方法是否為必須實現的方法。