@property是什么
@Property是聲明屬性的語法劳跃,它可以快速方便的為實例變量創(chuàng)建存取器名船,并允許我們通過點語法使用存取器诈茧。
存取器(accessor):指用于獲取和設(shè)置實例變量的方法。用于獲取實例變量值的存取器是getter纺念,用于設(shè)置實例變量值的存取器是setter贝椿。
創(chuàng)建存取器
手工創(chuàng)建存取器
我們先看兩段代碼:
//Fraction.h
#import <Foundation/Foundation.h>
@interface Fraction:NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
-(double) convertToNum;
上面代碼中numerator、denominator是Fraction類的實例變量陷谱,并且看到對這兩個實例變量都聲明了set/get方法烙博。
//Fraction.m
#import "Fraction.h"
@implementation Fraction
-(void) print
{
NSlog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator=n;
}
-(void) setDenominator: (int) d
{
denominator=d;
}
-(int) numerator
{
return numerator;
}
-(int) denominator
{
return denominator;
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator / denominator;
else
return 1.0;
}
@end
上面代碼是對實例變量存取器的實現(xiàn)。我們可以看到烟逊,存取器就是對實例變量進(jìn)行賦值和取值渣窜。按照約定賦值方法以set開頭,取值方法以實例變量名命名焙格。
使用@Property創(chuàng)建存儲器
@interface Fraction:NSObject
{
int numerator;
int denominator;
}
@property int numerator, denominator;
-(void) print;
-(double) convertToNum;
上面代碼中图毕,我們使用@property聲明兩個屬性,名稱與實例變量名稱相同眷唉。
@implementation Fraction
@synthesize numerator, denominator;
-(void) print
{
NSlog (@"%i/%i", numerator, denominator);
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator / denominator;
else
return 1.0;
}
@end
和手動生成存取器相比予颤,在.m文件中我們使用@synthesize自動生成這兩個實例變量的存取器,并且隱藏了存取器冬阳,雖然我們看不到存取器蛤虐,但它們確實是存在的。
總結(jié):
@property等同于在.h文件中聲明實例變量的get/set方法肝陪,@synthesize等同于在.m文件中實現(xiàn)實例變量的get/set方法驳庭。使用@property和synthesize創(chuàng)建存取器要比手動聲明兩個存取方法(getter和setter)更簡單。而且我們在使用屬性時可以使用點語法賦值或取值氯窍,語法更簡單饲常,更符合面向?qū)ο缶幊獭?/p>
不必單獨聲明實例變量
如果我們希望使用默認(rèn)的實例變量命名方式,那么我們在.m文件中就不需要使用@synthesize聲明狼讨,系統(tǒng)會幫我們自動完成(以“_實例變量名字”來命名)贝淤。
@synthesize numerator = _numerator;
@synthesize denominator = _denominator;
如果我們希望自己命名實例變量命,那么我們就使用@synthesize顯示聲明我們希望的實例變量名政供。
@property的特性
@property還有一些關(guān)鍵字播聪,它們都是有特殊作用的,比如上述代碼中的nonatomic布隔,strong离陶。
把它們分為三類,分別是:原子性衅檀,存取器控制招刨,內(nèi)存管理。
原子性
atomic(默認(rèn)):atomic意為操作是原子的哀军,意味著只有一個線程訪問實例變量计济。atomic是線程安全的,至少在當(dāng)前的存取器上是安全的排苍。它是一個默認(rèn)的特性沦寂,但是很少使用,因為比較影響效率淘衙,這跟ARM平臺和內(nèi)部鎖機制有關(guān)传藏。
nonatomic:nonatomic跟atomic剛好相反。表示非原子的彤守,可以被多個線程訪問毯侦。它的效率比atomic快。但不能保證在多線程環(huán)境下的安全性具垫,在單線程和明確只有一個線程訪問的情況下廣泛使用侈离。
存取器的控制
readwrite(默認(rèn)):readwrite是默認(rèn)值,表示該屬性同時擁有setter和getter筝蚕。
readonly: readonly表示只有g(shù)etter沒有setter卦碾。
內(nèi)存管理
主要涉及到assign铺坞、retain、strong洲胖、weak济榨、copy等情況,以及各自的使用場景绿映。
Strong:強引用擒滑,表示實例對象對傳入的對象有所有權(quán)關(guān)系。常用在:自定義對象叉弦,控制器對象丐一。
Weak:弱引用,在setter方法中淹冰,需要對傳入的對象不進(jìn)行引用計數(shù)加1的操作库车,也就是,對傳入的對象沒有所有權(quán)榄棵,當(dāng)該對象的引用計數(shù)為0時凝颇,該對象即被釋放,用weak聲明的實例變量指向nil疹鳄,即實例變量的值為0拧略。常用在:delegate對象,IBOutLet瘪弓。
Assign:簡單賦值垫蛆,不改變引用計數(shù),適合簡單數(shù)據(jù)類型如NSInteger腺怯、CGFloat袱饭、int、float等呛占。
Copy:把原來的對象完整復(fù)制另外一個地方虑乖,重新加載內(nèi)存區(qū),原來對象變了不影響新內(nèi)存區(qū)的對象晾虑。常用在:NSString疹味、NSArray、NSDictionary及其子類等帜篇。