當編譯器遇到屬性聲明時(參見《The Objective-C PRogramming Language》中的《Declared Properties》),它會產生與封閉類、類別或協議相關聯的描述性元數據。你可以使用方法訪問該元數據,支持通過類或協議中的名字查找屬性,獲得以 @encode 字符串表示的屬性類型,以及拷貝屬性的標志列表作為C字符串數組。已聲明的屬性的列表對于每個類和協議都是可用的。
Property 結構體定義了屬性描述符的不透明句柄。
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類型字符串屬性。編碼類型字符串的詳情,參見 Type Encodings;這個字符串的詳情,見 Property Type String 和 Property Attribute Description Examples。
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 類型字符串以及屬性的其他特征。
該字符串以跟著 @encode 類型和逗號的 T 開頭,最后以跟著后臺實例變量的名稱的 V 結束。在它們之間,屬性由以下描述符說明,以逗號分隔:
Table 7-1 Declared property type encodings
| Code | Meaning |
|---|---|
| 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 | The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,). |
| S | 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 | Specifies the type using old-style encoding. |
例子參見《Property Attribute Description Examples》。
給出這些定義:
enum FooManChu { FOO, MAN, CHU };struct YorkshireTeaStruct { int pot; char lady; };typedef struct YorkshireTeaStruct YorkshireTeaStructType;union MoneyUnion { float alone; double down; };下表展示了屬性聲明范例和 property_getAttributes 方法的響應字符串:
| Property declaration | Property description |
|---|---|
| @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 signed signedDefault; | Ti,VsignedDefault |
| @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; Note: the compiler warns: “no ‘assign’, ‘retain’, or ‘copy’ attribute is specified - ‘assign’ is assumed” | T@,VidDefault |
| @property int *intPointer; | T^i,VintPointer |
| @property void *voidPointerDefault; | T^v,VvoidPointerDefault |
| @property int intSynthEquals;(In the implementation block: @synthesize intSynthEquals=_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(assign) int intAssign; | Ti,VintAssign |
| @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 |
新聞熱點
疑難解答