#### 訪問成員變量
從面向對象的封裝角度考慮問題, 要想訪問類中的成員變量, 是要通過方法訪問的,?
成員變量前面要有作用域限定符(protected, public, private) ,?
這些存取權限修飾符我們將在后面介紹。?
成員變量的訪問, 是通過讀取方法(getter) 和設定方法(setter)。
訪問成員屬性:
可以使用點運算符.,或發送消息[]
以上一節中的音樂類為例子:
~~~
Song.h文件
@interface Song : NSObject {
NSString *title;
NSString *artist;
long int duration;
}
//操作方法
- (void)start;
- (void)stop;
- (void)seek:(long int)time;
//訪問成員變量方法
- (NSString *)title;?
- (void) setTitle:(NSString *) newTitle;
- (NSString *)artist;?
- (void) setArtist:(NSString *) newArtist;
- (long int)duration;?
- (void) setDuration:(long int) newDuration;
@end
Song.m文件
@implementation Song
- (void)start {
//開始播放
}
- (void)stop {
//停止播放
}
- (void)seek:(long int)time {
//跳過時間
}
//訪問成員變量方法
- (NSString *)title {
return title;
}
- (void) setTitle:(NSString *) newTitle {
title = newTitle;
}
- (NSString *)artist {
return artist;
}
- (void) setArtist:(NSString *) newArtist {
artist = newArtist;
}
- (long int)duration {
return duration;
}
- (void) setDuration:(long int) newDuration {
duration = newDuration;
}
@end
~~~
#### 小結
采用了封裝之后就可以通過存取方法訪問屬性,?
例如[mySong?title] 是取得title成員變量內容。?
如果不考慮封裝的問題, 單從技術上講Objective-C, 可以直接通過對象訪問成員變量的,?
訪問操作符是“->” ,?
例如:
mySong->title, 也可以取得title成員變量的內容。
需要指出的是,也可以對自定義的方法使用點運算符,不僅僅是使用在synthesize上(即屬性)。
注意:
點運算符和發消息都是可以的,但是,點運算符通常使用在屬性上,用于設置或取得實例變量的值。
方法在Apple的文檔中被標記為任務(Task),任務通常不是由點運算符執行的,
而是使用傳統的方括號形式的消息表達式作為首選的語法。
另外,使用合成(synthesize)的存取方法,屬性名稱的前面不要以new、alloc、copy和init這些此開頭。
這與編譯器的一些假定有關,因為編譯器會合成相應的方法。
#### 屬性
對于成員變量的訪問, 要通過讀取方法(getter) 和設定方法(setter) 。?
在實現部分也要實現這些讀取方法和設定方法,?
為了簡化這些瑣碎編碼Objective-C2.0提出屬性的概念,?
使用 @property關鍵字在接口部分定義屬性,?
在實現部分使用 @synthesize關鍵字在組裝和合成這些屬性。
這種可自動生成設值方法和取值方法(統稱為存取方法)。
具體步驟如下:
1)在接口部分中使用@property指令標識屬性。
~~~
@interface Fraction : NSObject
@property int numerator, denominator;
@end
~~~
2)在實現部分使用@synthesize指令即可。
~~~
@inplementation Fraction
@synthesize numerator, denominator;
@end
~~~
再次實現頭文件如下:
~~~
@interface Song : NSObject {
NSString *title;
NSString *artist;
long int duration;
}
//操作方法
- (void)start;
- (void)stop;
- (void)seek:(long int)time;
//訪問成員變量方法
@property(copy,readwrite) NSString *title;
@property(nonatomic,retain) NSString *artist;
@property(readonly) long int duration;
@end
~~~
#### 代碼說明:
聲明property的語法為: @property (參數) 類型 名字; ,?
這里的“參數” 主要分為3大類:?
?讀寫屬性(readwrite/readonly) ;?
?內存管理(assign/retain/copy) , 這些內存管理的參數, 我們將在內存管理小節部分介紹;?
?原子性atomicity(nonatomic) , 是關系線程線程安全的,
atomicity是原子性的線程安全的, 但是會影響性能。?
如果確定不考慮線程安全問題可以使用 nonatomic。
> 注意:
> 如果使用了@property指令,就不需要在實現部分聲明相應的實例變量。
通常,如果有稱為x的屬性,那么在實現部分包括以下行會導致編譯器自動實現一個取值方法x和一個設置方法setX:
@synthesize x;
因為生成的存取方法是高效的,并且在使用多個核心的多臺機器上,使用多線程時也可正常運行。
(這里的說法呢,就是說線程安全的)
實現.m文件如下:
~~~
@implementation Song
@synthesize title;
@synthesize artist;
@synthesize duration;
- (void)start {
//開始播放
}
- (void)stop {
//停止播放
}
- (void)seek:(long int)time {
//跳過時間
}
@end
~~~