IOS 開發學習總結objective-c物件導向之——合成存取方法與點文法

來源:互聯網
上載者:User

IOS 開發學習總結objective-c物件導向之——合成存取方法與點文法
合成存取方法

前面我們介紹了為成員變數自己實現 setter 方法和 getter 方法,但如果一個了類中有很多成員變數時,會非常的不便。
objective-c從 OC 2.0版本開始,自動合成了setter 方法和 getter 方法。而且,如果開發人員需要自己控制某個setter 方法和 getter 方法的實現時,可以自己提供 setter 方法和 getter 方法,開發人員提供的setter 方法和 getter 方法會覆蓋系統自動合成的相應方法。

使系統自動合成 setter 和 getter 的方法的步驟在類介面部分使用@property 指令定義屬性。——@property 指令放在屬性定義的前面,直接放在@interface,@end 之間定義。 在類實現的部分使用@synthesize 指令聲明該屬性。
當採用上面的2步後,會合成成對的 setter 和 getter 方法。還會自動在類的實現部分定義一個與 getter 方法同名的成員變數。這部分可以參見之前的一篇博文《【IOS 開發學習總結-OC-11】★objective-c物件導向之——封裝和存取控制符 》
如果為某個類定義了一個成員變數,並提供了相應的setter 和 getter 方法,那麼可以稱為定義了一個屬性(property)。
Xcode4.0後的編碼規範推薦將成員變數名定義為以底線開頭,比如在 Xcode 的模板代碼中有這樣的代碼: @synthesize window=_window; 該代碼的作用是:告訴系統合成的property對應的成員變數為_window, 而不是 window。
@synthesize的文法格式: @synthesize property名 =成員變數名; 或者是 @synthesize property名
@synthesize 後如果沒有有指定成員變數名,成員變數預設與合成的 getter 方法重名。
示範合成存取方法的用法。範例程式碼:
FKUser.h檔案:
#import @interface FKUser : NSObject// 使用@property定義3個property@property (nonatomic) NSString* name;@property NSString* pass;@property NSDate* birth;@end

FKUser.m檔案:

#import FKUser.h@implementation FKUser// 為3個property合成setter和getter方法,// 指定name property底層對應的成員變數名為_name@synthesize name = _name;@synthesize pass;@synthesize birth;// 實現自訂的setName:方法,添加自己的控制邏輯- (void) setName:(NSString*) name{    self->_name = [NSString stringWithFormat:@+++%@         , name];}@end

FKUserTest.m檔案:

#import FKUser.hint main(int argc , char * argv[]){    @autoreleasepool{        // 建立FKUser對象        FKUser* user = [[FKUser alloc] init];        // 調用setter方法修改user成員變數的值        [user setName:@admin];        [user setPass:@1234];        [user setBirth:[NSDate date]];        // 訪問user成員變數的值        NSLog(@管理員帳號為:%@,密碼為:%@,生日為:%@            , [user name] , [user pass] , [user birth]);    }}

程式通過@property,@synthesize 合成 setter,getter 方法後,程式就可以在後面通過setter,getter 方法存取成員變數的值。

定義@property時用到的特殊指示符assign

assign:指定對屬性只是簡單賦值,不更改對所賦的值的引用計數。主要適用於:NSInteger 等基本類型,以及 short,float,結構體等各種 C 資料類型。那麼問題來了,

為什麼NSInteger 等基本類型,以及 short,float,結構體等各種 C 資料類型不存在回收的問題呢?

iOS中的垃圾處理機制是根據一個對象的索引數(引用計數)來處理的,為0的時候表示沒有地方使用該對象,則該對象將被清除,而基礎資料型別 (Elementary Data Type)不屬於對象,它的建立和使用都是在記憶體中,超出對應方法體即被清除,所以不需要使用垃圾處理機制,無需記錄索引值(計數),不存在回收的問題。所以使用assgin。

atomic與nonatomic

atomic(nonatomic):指定合成的存取方法是否為原子操作。預設為atomic。
如果用atomic,那麼合成的存取方法都是安全執行緒的——當一個線程進入存,取方法的方法體後,其他線程無法進入該存,取方法,這樣可以避免多線程破壞對象的資料完整性。

copy

copy:使用 copy 指示符時,當調用 setter 方法對成員變數賦值時,會將被賦值的對象複製一個副本,再將副本賦值給成員變數。copy 會將原成員變數所引用對象的引用計數減1。

何時考慮使用 copy?

當成員變數的類型是可變類型或其子類是可變類型時,被賦值的對象可能在賦值之後被修改,如果程式不需要這種修改影響 setter 方法設定的成員變數的值,此時考慮用 copy 指示符。
樣本程式:
FKBook.h

#import @interface FKBook : NSObject// 使用@property定義1個property@property (nonatomic) NSString* name;@end

FKBook.m

#import FKBook.h@implementation FKBook@synthesize name;@end

FKBookTest.m

#import FKBook.hint main(int argc , char * argv[]){    @autoreleasepool{        FKBook* book = [[FKBook alloc] init];        //NSMutableString是NSString的子類        NSMutableString* str = [NSMutableString             stringWithString:@iOS講義];        // 對book的name屬性賦值        [book setName:str];        // 輸出book的name屬性        NSLog(@book的name為:%@ , [book name]);        // 修改str字串        [str appendString:@是一本很好的iOS學習圖書];        // 下面代碼將會看到book的name屬性也會被修改        NSLog(@book的name為:%@ , [book name]);    }}

編譯運行該程式後,輸出內容為:
book的name為:iOS講義
book的name為:iOS講義是一本很好的iOS學習圖書

如果我們不想 FKBook 的 name 屬性不會隨著NSMutableString對象的改變而改變,我們可以在定義 name 屬性的一行增加copy 指示符就可以了, @property (nonatomic,copy) NSString* name;

setter&getter

用於為合成的setter,getter方法指定自訂的方法名。
舉個栗子:getter=abc 指定 getter 方法名為 abc,setter=xyz:,則指定 setter 方法名為 xyz。注意:——setter方法不要忘了帶冒號,因為它要帶參數。
樣本程式:
FKItem.h

#import @interface FKItem : NSObject// 使用@property定義1個property,並指定自訂的getter、setter方法名@property (assign , nonatomic , getter=wawa , setter=nana:) int price;@end

FKItem.m

#import FKItem.h@implementation FKItem@synthesize price;@end

FKItemTest.m

#import FKItem.hint main(int argc , char * argv[]){    @autoreleasepool{        FKItem* item = [[FKItem alloc] init];        // 設定price屬性        [item nana:30];        // 訪問price屬性        NSLog(@item的price為:%d , [item wawa]);    }}

這裡的的 setPrice: 方法和 擷取的price 方法已經不存在,取而代之的是 nana 和 wawa。

readonly&readwrite

readonly指示系統只合成 getter 方法,不再合成 setter 方法。readwrite是預設值,2個方法都合成。

retain

使用retain指示符定義屬性時,當把某個對象賦值給該屬性時,該屬性原來所引用的對象的引用計數-1,被賦值對象的引用計數+1.
說明:在啟動 ARC 的情況下,一般少用 retain。但在未啟用 ARC 的情況下,retain是很有用的。
樣本程式:(下面的程式關閉了 ARC)
FKWin.h

#import @interface FKWin : NSObject// 使用@property定義1個property@property (nonatomic , retain) NSDate* date;@end

FKWin.m

#import FKWin.h@implementation FKWin@synthesize date;@end

FKWinTest.m

#import FKWin.hint main(int argc , char * argv[]){    FKWin* win = [[FKWin alloc] init];    NSDate* date = [[NSDate alloc] init];    // 第一次賦值時,date的引用計數為1    NSLog(@date的引用計數為:%ld , date.retainCount);    // 由於使用了retain指示符,賦值時導致date的引用計數+1    [win setDate:date];    // 下面輸出的引用計數為2    NSLog(@[win date]的引用計數為:%ld , [win date].retainCount);    // 釋放date的引用計數,date的引用計數-1    [date release];    // 下面輸出的引用計數為1    NSLog(@[win date]的引用計數為:%ld , [win date].retainCount);}
點文法

objective-c 允許使用簡化的點文法訪問屬性和對屬性賦值。其本質仍是調用 getter,setter 方法。
樣本程式:
FKCard.h

#import @interface FKCard : NSObject// 使用@property定義2個property@property (nonatomic , copy) NSString* flower;@property (nonatomic , copy) NSString* value;@end

FKCard.m

#import FKCard.h@implementation FKCard@synthesize flower;@synthesize value;@end

FKCardTest.m

#import FKCard.hint main(int argc , char * argv[]){    @autoreleasepool{        FKCard* card = [[FKCard alloc] init];        // 通過點文法對屬性賦值        card.flower = @♠;        card.value = @A;        // 通過點文法來訪問屬性值        NSLog(@我的撲克牌為:%@%@, card.flower, card.value);    }}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.