--------------------------------------------IOS期待與您交流!--------------------------------------------
一、點文法
1、沒有使用點文法的情況
此時我們使用setter和getter方法來通路對象的成員變量#import <Foundation/Foundation.h> @interface Person : NSObject { int _age; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { NSLog(@"調用了setAge方法"); _age = age; } - (int)age { NSLog(@"調用了age方法"); return _age; } @end int main() { // 沒有使用點文法的時候 Person *p = [Person new]; [p setAge:20]; int age = [p age]; NSLog(@"年齡是:%d", age); return 0; }
輸出結果:
2014-03-19 20:15:13.476 Test[470:303]調用了setAge方法
2014-03-19 20:15:13.477 Test[470:303]調用了age方法
2014-03-19 20:15:13.478 Test[470:303]年齡是:20
2、使用了點文法的情況
使代碼更簡潔了, 本質是方法調用#import <Foundation/Foundation.h> // Person方法的聲明和實作和上面一樣 int main() { // 使用點文法的時候 Person *p = [Person new]; p.age = 20; // 本質是 -> [p setAge:20]; int age = p.age; // 本質是 -> int age = [p age]; NSLog(@"年齡是:%d", age); return 0; }
輸出結果:
2014-03-19 20:15:13.476 Test[470:303] 調用了setAge方法
2014-03-19 20:15:13.477 Test[470:303] 調用了age方法
2014-03-19 20:15:13.478 Test[470:303] 年齡是:20
3、注意
- (void)setAge:(int)age { // 相當于 [self setAge:age],會引發死循環 self.age = age; } - (int)age { // 相當于 [self age],會引發死循環 return self.age; }
二、成員變量的作用域
public:在任何地方都能直接通路對象的成員變量
protected:可在目前類及其子類對象中直接通路對象的成員變量(預設的)
private:隻能在目前類中直接通路對象的成員變量
package:同一架構中能直接通路對象的成員變量
三、@property和@synthesize
1、以前的代碼方式
@interface Person : NSObject { int _age; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } @end
2、使用了@property和@synthesize
下面代碼和上面是等效的@interface Person : NSObject @property int age; @end @implementation Person @synthesize age = _age; @end
3、隻使用了@property
下面代碼和上面是等效的@interface Person : NSObject @property int age; @end @implementation Person @end
4、總結
1-> 隻用@property時,會産生3個效果(以@property int 為例)
1 生成 _age 成員變量(private的成員變量)
2 生成 age 的 setter 和 getter 方法的聲明
3 生成 age 的 setter 和 getter 方法的聲明
2-> 使用@property和@synthesize時,和上面的效果基本相同,不同在于@synthesize可以指定生成的成員變量的名稱。
如
就會等價于@interface Person : NSObject @property int age; @end @implementation Person @synthesize age = hello; @end
使用@synthesize時,推薦使用_age,這樣更符合約定@interface Person : NSObject { int hello; } - (void)setAge:(int)age; - (int)age; @end @implementation Person - (void)setAge:(int)age { hello = age; } - (int)age { return hello; } @end
5、此外
隻有使用了@property ,才會自動生成private的_age。使用@synthesize 用來改變@property 生成的成員變量名。
如果自己隻實作了setter 方法,會自動生成getter 方法和帶下劃線的成員變量(_age)
如果自己隻實作了getter 方法,會自動生成setter 方法和帶下劃線的成員變量(_age)
如果自己實作了setter 方法和getter 方法,就不會自動生成成員變量(_age),需要我們手動生成
四、構造方法(init)
1、new方法
我們可以通過new 方法來生成一個對象Person *p = [Person new];
其實new 是分兩步來生成對象的
* 調用+alloc 方法來給對象配置設定記憶體空間
* 調用-init 方法給對象的成員變量初始化成預設的值
缺點:不能在建立對象的同時進行一些必要的初始化
2、alloc 和 init 方法
重寫構造方法的目的:為了讓對象一建立出來,成員變量就由一些預設的值@interface Person : NSObject @property int age; @end @implementation Person // 需要重寫init 方法來滿足自己的初始化要求 - (id)init { // 必須先調用父類的構造方法對父類的變量進行初始化 if (self = [super init]) { _age = 20; } return self; } @end int main() { Person *p = [[Person alloc] init]; // 和 Person *p = [Person new]; 一樣的效果 NSLog(@"年齡是:%d", p.age); return 0; }
輸出:
2014-03-19 21:20:29.860 Test[644:303]年齡是:20
3、自定義init 方法(自定義構造方法)
@interface Person : NSObject @property int age; @end @implementation Person - (id)initWithAge:(int)age { if (self = [super init]) { _age = age; } return self; } @end
輸出: 2014-03-19 21:25:55.821 Test[656:303]年齡是:24int main() { Person *p = [[Person alloc] initWithAge:24]; NSLog(@"年齡是:%d", p.age); return 0; }
五、分類(Category)
作用:在不改變類的基礎上增加一些方法
類名:類名 (分類名)
分類名一般是子產品名
如想為Person類增加一個添加一個分類LXZ
Person+LXZ.h
Person+LXZ.m#import "Person.h" @interface Person (LXZ) - (void)study; @end
main.m#import "Person+LXZ.h" @implementation Person (LXZ) - (void)study { NSLog(@"lxz study"); } @end
#import <Foundation/Foundation.h> #import "Person.h" #import "Person+LXZ.h" int main() { Person *p = [[Person alloc] init]; [p study]; return 0; }
輸出:
2014-03-19 21:58:17.997 OCTest[841:303] lxz study
注意
1 分類隻能增加方法,不能增加成員變量
2 分類方法中可以通路原來類中的成員變量
3 分類可以重新實作原來類中得方法,這會覆寫原來類中的方法,使原來類中的方法失效
4 方法調用優先級:分類(最後被編譯的分類) -> 原來類
六、SEL
在OC中,對象或類每當調用一個方法時,會把方法包裝成一個SEL的資料類型,然後去類對象中找對應的SEL(類對象中有該類的所有方法的SEL,每個方法對應一個SEL)。若找到,則調用相應的方法,若沒找到,則報錯。
以上面的 Person 類為例,看看調用age的getter方法的方式有哪些
方式一(隐式的使用了SEL)
方式二(顯式的使用了SEL)[p age];
方式三(顯示的使用了SEL)[p performSelector:@selector(age)];
SEL sel = NSSelectorFromString(@"age"); [p performSelector:sel];
--------------------------------------------IOS期待與您交流!--------------------------------------------
詳細請檢視:http://edu.csdn.net