屬性概念
屬性是OC的一項(xiàng)特性,用于封裝對象中的數(shù)據(jù)
OC對象通常會把其所需要的數(shù)據(jù)保存為各種屬性
屬性通過存取方法來訪問(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
- 訪問屬性時,可以使用點(diǎn)語法,是一個編譯器的特性,編譯器會把“點(diǎn)語法”轉(zhuǎn)換為對存取方法的調(diào)用,使用點(diǎn)語法和直接調(diào)用存取方法的效果一致。點(diǎn)語法在等號左邊,那么編譯器會自動轉(zhuǎn)換為setter方法,點(diǎn)語法在等號右邊或沒有等號,那么編譯器會自動轉(zhuǎn)化為getter方法
Person *per = [[Person alloc]init];
per.firstName = @"Bob";//等同于[per setFirstName:@"Bob"];
NSString *lastName = per.lastName; //等同于NSString *lastName = [per lastName];
- 在使用屬性的過程中,編譯器會自動編寫訪問這些屬性所需要的方法,這個過程叫“自動合成”。這個過程是由編譯器在編譯期執(zhí)行的。除了生成存取方法之外,編譯期還會自動向類中添加適當(dāng)?shù)念愋偷膶?shí)例變量,并且在屬性名前面加下劃線,以此作為實(shí)例變量的名字
#import "Person.h"
@implementation Person
@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@end
- 若不想讓編譯器自動合成存取方法,需要使用@dynamic,它會通知編譯器不要自動創(chuàng)建屬性所用的實(shí)例變量,也不要為其創(chuàng)建存儲方法
#import "Person.h"
@implementation Person
@dynamic firstName;
@dynamic lastName;
@end
//當(dāng)你在通過點(diǎn)語法或調(diào)用方式時程序就會崩潰,因?yàn)椴]有setter、getter方法
Person *per = [[Person alloc]init];
per.firstName = @"Bob";
NSString *lastName = NSString *lastName = [per lastName];
屬性特質(zhì)
屬性的特質(zhì)也會影響編譯器所生成的存取方法,分為四類:原子性、讀寫權(quán)限、內(nèi)存管理關(guān)鍵字、方法名
-
原子性(atomic、nonatomic)
- atomic(默認(rèn)): 假設(shè)多個線程訪問同一屬性,那么所有不同線程上的操作都將依次順序執(zhí)行,該屬性讀取是安全的
- nonatomic :如有兩個線程訪問同一個屬性,會出現(xiàn)無法預(yù)料的結(jié)果,一般屬性設(shè)置都是nonatomic,因?yàn)閕OS中使用同步鎖的開銷比較大,會影響性能
-
讀寫權(quán)限
- readwrite:屬性擁有g(shù)etter、setter方法
- readonly: 屬性擁有g(shù)etter方法
-
內(nèi)存管理關(guān)鍵字
- assign:用于修飾數(shù)值類型,是簡單賦值操作
- strong:為這種屬性設(shè)置新值時,設(shè)置方法會先保留新值,并釋放舊值,然后再把新值設(shè)置過去
- weak:為這種屬性設(shè)置新值時,設(shè)置方法既不會保留新值,也不釋放舊值,所修飾的對象銷毀時,該屬性會被置為nil
- unsafe_unretained:用于修飾對象類型,所修飾的對象銷毀時,該屬性不會被置為nil
- copy:設(shè)置方法并不保留新值,而是將其拷貝一份。(當(dāng)屬性類型為NSString時,經(jīng)常用copy,因?yàn)閭鬟f給設(shè)置方法新值有可能指向一個NSMutableString類的實(shí)例,這個類是NSString的子類,若不拷貝字符串,那么設(shè)置完屬性后,字符串的值就可能會在對象不知情的情況下被人更改,所有要拷貝一份不可變的字符串,確保對象中的字符串的值不會無意間變動)
- 方法名
getter=:指定獲取方法的方法名,
@property (nonatomic,getter=isOn) BOOL on;setter=:指定設(shè)置方法的方法名,這種用發(fā)不常見,此處不做太多解釋