聲明屬性
當編譯器遇到屬性聲明(see Declared Properties in The Objective-C Programming Language)時,編譯器產生以類、分類、協議進行封裝的描述性元數據。你能夠使用函數來獲取這個元數據,該函數通過類名或者協議名來支持查看一個類,從而以@encode字符串的形式來獲取屬性類型,以C字符串數組的形式獲取屬性描述列表,聲明屬性的列表是用于每個類和協議。
屬性類型及功能
屬性結構體定義了一個不透明的屬性描述
typedef struct objc_property *Property;
你能使用該函數class_copyPropertyList和protocol_copyPropertyList以數組的形式獲取屬性與類(包括加載類)和協議 分別為:
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)
例如,下邊給定的類描述
@interface Lender : NSObject {
float alone;
}
@property float alone;
@end
你能獲取屬性的列表,通過使用:
id LenderClass = objc_getClass("Lender");
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
你能使用property_getName函數去獲取屬性名字
const char *property_getName(objc_property_t property)
你能使用函數class_getProperty和protocol_getProperty得到一個引用,通過一個給定的類名和給定協議分別:
objc_property_t class_getProperty(Class cls, const char *name)
objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)
你能使用property_getAttributes函數去獲取屬性名和以@encode 字符串的編碼類型
const char *property_getAttributes(objc_property_t property)
放在一起,你能還是用下邊代碼打印所有屬性的列表
id LenderClass = objc_getClass("Lender");
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
屬性類型
你能使用property_getAttributes函數獲取一個屬性的名稱和以@encode 類型的編碼,和屬性的其他描述。這個字符串以"T"跟隨@encode類型開始, 并且以"V"跟隨返回實例變量名字為結尾。在這兩者之間,指定了一下描述,通過“,”分割:
表7-1 聲明屬性編碼類型
Code | 意義 |
---|---|
R | The property is read-only (readonly) |
C | The property is a copy of the value last assigned (copy). |
& | The property is a reference to the value last assigned (retain). |
N | The property is non-atomic (nonatomic). |
G<name> | The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,). |
S<name> | The property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,). |
D | The property is dynamic (@dynamic). |
W | The property is a weak reference (__weak). |
P | The property is eligible for garbage collection. |
t<encoding> | Specifies the type using old-style encoding. |
屬性描述
提供這些描述
enum FooManChu { FOO, MAN, CHU };
struct YorkshireTeaStruct { int pot; char lady; };
typedef struct YorkshireTeaStruct YorkshireTeaStructType;
union MoneyUnion { float alone; double down; };
下邊表格展示了屬性描述樣例和通過property_getAttributes返回的相應的字符串
屬性聲明 | 屬性描述 |
---|---|
@property char charDefault; | Tc,VcharDefault |
@property double doubleDefault; | Td,VdoubleDefault |
@property enum FooManChu enumDefault; | Ti,VenumDefault |
@property float floatDefault; | Tf,VfloatDefault |
@property int intDefault; | Ti,VintDefault |
@property long longDefault; | Tl,VlongDefault |
@property short shortDefault; | Ts,VshortDefault |
@property struct YorkshireTeaStruct structDefault; | T{YorkshireTeaStruct="pot"i"lady"c},VstructDefault |
@property YorkshireTeaStructType typedefDefault; | T{YorkshireTeaStruct="pot"i"lady"c},VtypedefDefault |
@property union MoneyUnion unionDefault; | T(MoneyUnion="alone"f"down"d),VunionDefault |
@property unsigned unsignedDefault; | TI,VunsignedDefault |
@property int (*functionPointerDefault)(char *); | T^?,VfunctionPointerDefault |
@property id idDefault; | T@,VidDefault |
@property int *intPointer; | T^i,VintPointer |
@property void *voidPointerDefault; | T^v,VvoidPointerDefault |
@property int intSynthEquals; | Ti,V_intSynthEquals |
@property(getter=intGetFoo, setter=intSetFoo:) int intSetterGetter; | Ti,GintGetFoo,SintSetFoo:,VintSetterGetter |
@property(readonly) int intReadonly; | Ti,R,VintReadonly |
@property(getter=isIntReadOnlyGetter, readonly) int intReadonlyGetter; | Ti,R,GisIntReadOnlyGetter |
@property(readwrite) int intReadwrite; | Ti,VintReadwrite |
@property(retain) id idRetain; | T@,&,VidRetain |
@property(copy) id idCopy; | T@,C,VidCopy |
@property(nonatomic) int intNonatomic; | Ti,VintNonatomic |
@property(nonatomic, readonly, copy) id idReadonlyCopyNonatomic; | T@,R,C,VidReadonlyCopyNonatomic |
@property(nonatomic, readonly, retain) id idReadonlyRetainNonatomic; | T@,R,&,VidReadonlyRetainNonatomic |