iOS中setter方法 、getter方法、點語法、@property
阿新 • • 發佈:2019-02-07
屬性概念
屬性是OC的一項特性,用於封裝物件中的資料
OC物件通常會把其所需要的資料儲存為各種屬性
屬性通過存取方法來訪問(setter、getter)
例如:在Person類中定義了2個屬性
- 通過@property語法,編譯器會自動生成一套存取方法
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@end
等同於
#import <Foundation/Foundation.h> @interface Person : NSObject - (void)setFirstName:(NSString *)firstName; - (NSString *)firstName; - (void)setLastName:(NSString *)lastName; - (NSString *)lastName; @end
- 訪問屬性時,可以使用點語法,是一個編譯器的特性,編譯器會把“點語法”轉換為對存取方法的呼叫,使用點語法和直接呼叫存取方法的效果一致。點語法在等號左邊,那麼編譯器會自動轉換為setter方法,點語法在等號右邊或沒有等號,那麼編譯器會自動轉化為getter方法
Person *per = [[Person alloc]init];
per.firstName = @"Bob";//等同於[per setFirstName:@"Bob"];
NSString *lastName = per.lastName; //等同於NSString *lastName = [per lastName];
- 在使用屬性的過程中,編譯器會自動編寫訪問這些屬性所需要的方法,這個過程叫“自動合成”。這個過程是由編譯器在編譯期執行的。除了生成存取方法之外,編譯期還會自動向類中新增適當的型別的例項變數,並且在屬性名前面加下劃線,以此作為例項變數的名字
#import "Person.h"
@implementation Person
@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@end
- 若不想讓編譯器自動合成存取方法,需要使用@dynamic,它會通知編譯器不要自動建立屬性所用的例項變數,也不要為其建立儲存方法
#import "Person.h"
@implementation Person
@dynamic firstName;
@dynamic lastName;
@end
//當你在通過點語法或呼叫方式時程式就會崩潰,因為並沒有setter、getter方法 Person *per = [[Person alloc]init]; per.firstName = @"Bob"; NSString *lastName = NSString *lastName = [per lastName];
屬性特質
屬性的特質也會影響編譯器所生成的存取方法,分為四類:原子性、讀寫許可權、記憶體管理關鍵字、方法名
-
原子性(atomic、nonatomic)
- atomic(預設): 假設多個執行緒訪問同一屬性,那麼所有不同執行緒上的操作都將依次順序執行,該屬性讀取是安全的
- nonatomic :如有兩個執行緒訪問同一個屬性,會出現無法預料的結果,一般屬性設定都是nonatomic,因為iOS中使用同步鎖的開銷比較大,會影響效能
-
讀寫許可權
- readwrite:屬性擁有getter、setter方法
- readonly: 屬性擁有getter方法
-
記憶體管理關鍵字
- assign:用於修飾數值型別,是簡單賦值操作
- strong:為這種屬性設定新值時,設定方法會先保留新值,並釋放舊值,然後再把新值設定過去
- weak:為這種屬性設定新值時,設定方法既不會保留新值,也不釋放舊值,所修飾的物件銷燬時,該屬性會被置為nil
- unsafe_unretained:用於修飾物件型別,所修飾的物件銷燬時,該屬性不會被置為nil
- copy:設定方法並不保留新值,而是將其拷貝一份。(當屬性型別為NSString時,經常用copy,因為傳遞給設定方法新值有可能指向一個NSMutableString類的例項,這個類是NSString的子類,若不拷貝字串,那麼設定完屬性後,字串的值就可能會在物件不知情的情況下被人更改,所有要拷貝一份不可變的字串,確保物件中的字串的值不會無意間變動)
-
方法名
-
getter=:指定獲取方法的方法名,
@property (nonatomic,getter=isOn) BOOL on;
-
setter=:指定設定方法的方法名,這種用發不常見,此處不做太多解釋
-