文件類型說明:
.h 頭文件,用於定義類、實例變量及類中的方法等定義信息(interface)。
.m 源文件,定義方法體,可實現objce-c和c方法(implementation)。
.mm c++源文件java
引用頭文件:
可經過#import關鍵字引入想要使用的頭文件,該關鍵字做用通#include相同,不過import會確保每一個文件只會被引用一次。c++
object-c中類的定義有兩部分:interface和implementation
interface部分包含類的定義以及實例變量和方法。interfache一般定義在.h(頭)文件中;
implementation部分包含方法的實現部分(方法體),implementation一般定義在.m(源)文件中。
框架
1 @interface MyClass : NSObject 2 { 3 int count; 4 id data; 5 NSString* name; 6 } 7 -(id)initWithString:(NSString*)aName; 8 +(MyClass*)createMyClassWithString:(NSString*)aName; 9 @end
在上述代碼中,包含了如下信息:
名爲MyClass的類,繼承於Cocoa框架中的NSObject類;
定義了3個成員變量:count、data和name(@protected)
以及聲明瞭2個方法
實例變量也能夠放到源文件中定義,如:函數
1 // 源文件中的:NSObject爲可選,通常狀況下不用寫 2 @implenmentation MyClass :NSObject 3 { 4 int count; 5 int data; 6 NSString *name; 7 } 8 9 -(id)initWithString:(NSString*)aName 10 { 11 ... 12 }
但須要注意的是,若成員變量定義在源文件中而非頭文件中,則變量的訪問權限都爲@private.this
object-c支持強類型和弱類型兩種方式定義一個對象變量:
強類型定義時變量類型即類命,且爲指針類型
弱類型定義使用id型定義spa
1 MyClass *myObject; // 強類型定義 2 id myObject; //弱類型定義
方法的定義和引用:
Object-C中的方法同其它面嚮對象語言同樣,分兩種方法:實例方法(-)和類方法(+)(靜態方法)。
實例方法須要經過類的實例去調用,而靜態方法可直接經過類名去調用。指針
1 - (void)insertObject:(id)anObject atIndex:(NSUInter)index;
上述代碼中定義了一個名爲"insertObject:atIndex"的實例方法,該方法無返回值,並定義了2個形參,類型分別爲id和NSUInter。code
在定義一個方法時,也能夠不指定參數名,如:orm
1 // 聲明一個沒有參數名的方法 2 -(int) set: (int) n: (int) d; 3 4 // 方法調用 5 [object set : 4 : 5];
方法的調用:
在Object-C中,調用一個方法叫作發送消息,方法調用語句定義在中括號"[]"中:對象
1 [myArray insertObject:anObject atIndex:0];
爲了不生成大量的臨時變量,Object-C容許嵌套調用方法,使一個方法的返回值看成另外一個方法的參數,如:
1 [[myAppObject theArray] inserObject:[myAppObject objectToInsert] atIndex:0];
成員變量:
默認狀況下,Object-C中的成員變量爲@protected,可經過@public,@private關鍵字修改爲員變量的可見性(只有成員變量擁有這些屬性)。
1 @interface MyObject : NSObject 2 { 3 // 成員變量要定義在大括號中 4 @public int n1; 5 @private int n2; 6 @protected int n3; 7 } 8 ...... 9 @end 10 11 // 經過類實例訪問public的成員變量: 12 MyObject *mo = [[MyObject alloc] init]; 13 mo->n1;
若要訪問受保護的成員變量,須要在類中定義相應的get和set方法,經過類實例調用這些方法來達到訪問或設置這些成員變量的目的。
訪問器 :
在Object-C中,提供了@property和@synthesize兩個關鍵字,經過這兩個關鍵字,能夠高效的爲每一個指定的成員變量設定set方法和get方法,稱爲屬性
1 // 頭文件 2 @interface MyObject : NSObject 3 { 4 @property int n1, n2; 5 } 6 ... 7 @end 8 9 // 源碼文件 10 @implementation MyObject 11 12 @synthesize n1, n2; 13 ... 14 @end
在上述代碼中,Object-C會自動建立4個方法:n一、n二、setN1和setN2。
可經過對象實例直接調用這4個方法
MyObject *mo = [[MyObject alloc] init]; int l_n1, l_n2; [mo setN1:4]; [mo setN2:8]; l_n1 = [mo n1]; l_n2 = [mo n2];
Object-C也支持使用"."符號來訪問properties
1 mo.n1 = 5;
這種方式一樣適用於調用方法
變量範圍
Object-C中的變量範圍同C同樣,在{}中定義的變量屬於本地變量,只能在{}中使用,本地變量默認初始化值爲nil。一樣方法的傳值方式是傳值引用,但當傳遞對象時是地址引用。
Object-C中也支持靜態變量,經過static關鍵字,如:
1 static int n = 0;
靜態變量默認初始值爲0,同C同樣。注:靜態變量一樣只能在定義的範圍內使用。
self變量至關於java中的this。
繼承
Ojbect-C中的繼承同java相同,都是單一繼承關係,要繼承一個類,可寫做:
1 @interface ClassA : NSObject 2 3 @end
其中NSObject類是最頂層類,通常全部類的最終父類都是它。
在子類中能夠訪問父類中的非private變量的實例變量和方法(靜態方法和實例方法)。
注:只能訪問非private屬性的成員變量,說明該變量必須定義在interface中(類的聲明中),由於在implementation中聲明的成員變量所有都是private。
在子類中經過super訪問父類中的方法,如:
1 [super init];
NSObject類經常使用方法:
方法名 | 說明 |
-(BOOL) isKindOfClass: class-object |
Is the object a member of class-object or a descendant? |
-(BOOL) isMemberOfClass: class-object |
Is the object a member of class-object? |
-(BOOL) respondsToSelector: selector |
Can the object respond to the method specified by selector? |
+(BOOL) instancesRespondToSelector: selector |
Can instances of the specified class respond to selector? |
+(BOOL)isSubclassOfClass: class-object |
Is the object a subclass of the specified class? |
-(id) performSelector: selector |
Apply the method specified by selector. |
(id) performSelector: selector withObject: object |
Apply the method specified by selector passing the argument object. |
-(id) performSelector: selector withObject: object1 withObject: object2 |
Apply the method specified by selector with the arguments object1 and object2. |
class-object是一個類對象,經過class方法生成,可經過類名和實例名調用class方法生成,如:
1 [Square class]; // Square 是一個類名 2 [mySquare class]; // mySquare 是一個實例 3 4 // 驗證兩個實例是否屬於同一個類 5 if ([obj1 class] == [obj2 class]) 6 { 7 ... 8 } 9 10 // 驗證myFan是否屬於Fraction,便是否是Fraction的實例 11 [myFan isMemberOfClass: [Fraction class]]
selector是一個SEL類型的變量(C中的函數指針),直接經過@selector生成 ,如:
// 爲alloc方法生成一個SEL類型變量 @selector (alloc) @selector (setTo:over:) // 查看Fraction類中是否含有setTo:over方法 // 該方法也去父類中查找 [Fraction instancesRespondToSelector: @selector(setTo:over)];
經過performSelector動態調用函數:
1 @implementation Fraction 2 -(void) setTO:(int) a Over:(int)b 3 { 4 ... 5 } 6 -(void) print 7 { 8 // 經過performSelector方法調用setTo:Over 9 // 傳遞2個整數參數4和5 10 [self performSelector:@selector(setTo:Over) withObject:4 withObject:5] 11 } 12 @end
1 if ([graphicObject respondsToSelector: action] == YES) 2 [graphicObject performSelector: action] 3 else 4 // error handling code here
異常
使用@try和@catch捕獲異常:
1 @try 2 { 3 ... 4 } @catch(NSException *exception) 5 { 6 ... 7 } 8 // 可選的放置一個@finally,該語句不管是否有異常發生,都會執行
編寫類的構造函數
可爲一個類編寫多個不一樣的初始化函數,實例化類時經過指定不一樣的初始化函數執行不一樣的初始化操做
1 -(Fraction *) initWith: (int) n over: (int) d { 2 self = [super init]; 3 if (self) 4 [self setTo: n over: d]; 5 return self; 6 }
重寫init方法
1 /* 2 * 注,該方法應該返回id類型, 3 * 而不是指定的類的類型 4 * 若是其它類繼承自該類,初始化子類時候返回的類型就會不正確 5 */ 6 7 -(id) init 8 { 9 return [self initWith:0 over:0]; 10 }
在類外部定義的變量會成爲全局變量,在任何類和方法中(包括其它文件)中均可以訪問這個變量。
關鍵字extern可用來在類和方法內部訪問全局變量,同PHP的global相似,但切記:
extern是聲明,而不是定義。
在變量前使用extern關鍵字,並不會爲該變量分配內存,僅僅是將該變量標識爲全局變量,因此不能夠在使用extern定義變量時賦值。
枚舉
Object-C支持枚舉類型,格式爲:
1 // 定義枚舉 2 enum flag { false, true }; 3 4 // 聲明兩個枚舉變量,該枚舉變量的值只能是true或false 5 enum flag endOfData, matchFound; 6 7 // 定義枚舉 8 enum direction { up, down, left = 10, right }; 9 10 // 或 11 enum boolean { no = 0, false = 0, yes = 1, true = 1 };