@property 的使用
在物件導向設計方法中我們會使用封裝來保護類別成員(成員亦包含了attribute與method),我們通常會寫method來存取attribute,命名為getter與setter,以下示範objective C的getter setter作法:
A.h
#import <Foundation/Foundation.h>
@interface A : NSObject {
int attr;
}
-(int)attr; //習慣上objective C不會在getter寫上get, 而是直接使用attribute作為getter
-(void)setAttr:(int)a;
@end
A.m
#import "A.h"
@implementation A
- (int)attr {
return self->attr; //原則上不加self也可以, 加了就可以跟method內的變數作區隔
}
-(void)setAttr: (int) a {
self->attr = a;
}
@end
當你使用以上的寫法作為getter與setter時,您在程式中使用實體物件時,就可以用”.”的方式來作存取, 方在 assignment的左邊代表setter, 在右邊代表getter,示範如下:
main.m
#import <Foundation/Foundation.h>
#import "A.h"
int main(int argc, const char * argv[]) {
A *a = [A alloc];
[a.attr 30]; // assign 30 給這個物件的attribute
printf("The attribute of A is %d", a.attr); //取出a.attr的值, 會印出The attribute of A is 30
[a release];
}
是不是每次都要用傳統的作法才能達成”.”的取用呢? 其實Objective C安排了一個比較簡單的作法,就是@property,那為甚麼要先介紹上面的做法呢?很簡單因為使用任何捷徑都應該先知道他的原理吧?知道了原理未來才不會在debug中苦哈哈。使用@property的寫法如下:
A.h
#import <Foundation/Foundation.h>
@interface A : NSObject {
int attr;
}
@property int attr; //這樣就會自動建立gettery與setter
@end
A.m
#import "A.h"
@implementation A
@synthesize attr; // 舊版的xcode需要成雙寫property與synthesize,新版的只要寫property其實就可以了,
//synthesize可以讓你改property的名字, 寫法是 @synthesize attr = ppp; (就改成ppp了)
@end
main.m
#import <Foundation/Foundation.h>
#import "A.h"
int main(int argc, const char * argv[]) {
A *a = [A alloc];
[a.attr 30]; // 一樣可以使用
printf("The attribute of A is %d", a.attr); //取出a.attr的值, 會印出The attribute of A is 30
[a release];
}
基本上使用@property 會自動作三件事情:
- 建立了 setPropertyName (setter)
- 建立了 propertyName (getter)
- 建立了 propertyName (attribute)
*這些method是可以被override的, 所以使用了@property後, 你也可以改寫成自己想用的方式。
@property的設定 //用來設定property的參數
讀寫控制
- readwrite (預設): 可以讀寫,setter和getter方法都會自動加入
- readonly: 只能讀, 只會加getter的方法
setter相關部分
- assign(預設): 用於只會和可量度的數值作用的情況, _abc = b;
- retain/strong 在指定時會呼叫物件的retain指令, 然後前一個數值會release掉
- copy: 在指定時會呼叫物件的copy指令, 然後前一個數值會release掉 (一定要實作NSCopy的Protocol, 否則會掛點)
atomicity (單一性)
- atomic (預設): 會讓屬性有執行緒安全(thread-safe)的特性
- nonatomic: synthesize的存取者會直接回傳數值