天天看點

[email protected]和@synthesize

對于iOS的開發, 是一個逐漸學習了解的過程. 

下面說一下對于Objective-C 中的 @property和@synthesize的了解。

在這之前先講講通路器(Accessor),也就是我們所知道的setter和getter方法。《Cocoa Design Patterns》中的将它歸類為基礎模式中的一種。通路器是很重要的技術,用來通路和設定對象的執行個體變量(不是指對象本身,而是對象中的屬性)。有時候可能需要用不同的方式或者通過計算等方式來擷取或設定執行個體變量,通路器給了我們很大的靈活性。在Cocoa中通路器有很多的優點:

1. 實作靈活性。 可以在通路器中改變并實作不同的執行個體變量通路方式而不影響其他代碼。

2. 可維護性。通過通路器對執行個體變量的更改易于維護。

3. 記憶體管理。通路器方法提供了簡單的方法去遵守Cocoa的約定把記憶體管理代碼隔離在少部分代碼中。

4. 支援KVC和KVO。 KVC和KVO是很強大的技術。但是它們依賴于正确命名通路器。

下面這段代碼簡單的實作了一個通路器(setter和getter):

//setter

-(void)setName:(NSString *)name

{  //_name 是執行個體變量

    if(_name != name)

    {

        [_name release];

        _name = [_name retain];

    }

}

//getter

-(NSString *)name

{

    return _name;

}

上面代碼中的setter中還涉及到一定的記憶體管理,這個技術很重要,那麼有沒有一種更友善的方法去做呢?

答案就是@property和@synthesize。它們是Objective-C 2.0加入的指令,前者用于聲明,後者用于合成通路器,結合使用就可以自動生成通路器了。

下面這段代碼使用@property和@synthesize:

@property (nonatomic, copy) NSString *name;

@synthesize name = _name;

在@property中還有其他幾個關鍵字,它們都是有特殊作用的,将它們分為三類分别是:原子性,通路器控制,記憶體管理。

1. 原子性

    atomic(預設):atomic意為操作是原子的,意味着隻有一個線程通路執行個體變量。atomic是線程安全的至少在目前的訪器上我是安全的。它是一個預設的,但是很少使用。它的比較慢,這跟ARM平台和内部鎖機制有關。

    nonatomic: nonatomic跟atomic剛好相反。表示非原子的,可以被多個線程通路。它的速度比atomic快。但不能保證在多線程環境下的安全性,在單線程和明确隻有一個線程通路的情況下廣泛使用。

2. 通路器控制

    readwrite(預設):readwrite是預設的,表示同時擁有setter和getter。

    readonly: readonly 表示隻有getter沒有setter。

3. 記憶體管理

    retain:使用了retain意味着執行個體變量要擷取傳入參數的所有權。具體表現在setter中對執行個體變量先release然後将參數 retain之後傳給它。下面這段代碼展示了retain類似的行為:

-(void)setStuName:(NSString *)stuName

{

    if(_stuName != stuName)

    {

        [_stuName release];

        _stuName = [stuName retain];

    }

}

    assign(預設):用于值類型,如int、float、double和NSInteger,CGFloat等表示單純的複制。還包括不存在所有權關系的對象,比如常見的delegate。

    strong:是在ARC伴随IOS引入的時候引入的關鍵字是retain的一個可選的替代。表示執行個體變量對傳入的參數要有所有權關系即強引用。strong跟retain的意思相同并産生相同的代碼,但是語意上更好更能展現對象的關系。

    weak: weak跟assign的效果相似,不同的是weak在對象被回收之後自動設定為nil。而且weak智能用在iOS 5或以後的版本,對于之前的版本,使用unsafe_unretained。

    unsafe_unretained:weak的低版本替代。

    copy:copy是為是執行個體變量保留一個自己的副本。