1. 程式人生 > >iOS中setter方法 、getter方法、點語法、@property

iOS中setter方法 、getter方法、點語法、@property

屬性概念

屬性是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=:指定設定方法的方法名,這種用發不常見,此處不做太多解釋