objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
函數是runtime
中的一個函數,用來 copy 一份類對象的屬性列表,返回值爲objc_property_t *
類型的數組。而後就能夠遍歷這個數組取出每一個屬性值。幾乎每一個字典轉模型框架都須要這個函數。c++
- (NSDictionary *)properties_aps { NSMutableDictionary *props = [NSMutableDictionary dictionary]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList([self class], &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; NSString *propertyName = [[[NSString alloc] initWithCString:property_getName(property)] autorelease]; id propertyValue = [self valueForKey:(NSString *)propertyName]; if (propertyValue) [props setObject:propertyValue forKey:propertyName]; } free(properties); return props; }
這段代碼中就包含了取屬性的函數:objective-c
objc_property_t *properties = class_copyPropertyList([self class], &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; }
objc_property_t *
類型的properties
數組,取出下標,獲得的是objc_property_t
類型的數組元素。數組
這個寫法忽然感受有些不解,由於若是咱們用int
來代替objc_property_t
:框架
int main(int argc, const char * argv[]) { int *arr = {1,2,3}; arr[1] = 10; int a = arr[1]; NSLog(@"%d", a); return 0; }
這樣顯然是不行的,int *
只是一個指針,C語言中,數組的本質是指針加偏移量,因此當給arr[1]
賦值時,至關因而給arr
這個指針偏移了8bit,然而咱們並無爲後面的地址開闢內存空間,天然就形成了EXC_BAD_ACCESS
錯誤。函數
那麼,該怎麼寫成runtime裏的那段代碼同樣type *
類型的foo
數組變量,能夠用foo[1]
取得一個type
類型的數組元素呢?學習
因此咱們要分析,上面那個int
的寫法是怎麼不對的。由於在給int *arr
初始化時,並無開闢一個sizeof(int)*count
大小的內存空間。指針
之因此若是寫成int arr[3]
就能夠,是由於這麼寫,C語言數組的本質是就是指針加偏移量。初始化了一個int指針,並且給了3*sizeof(int)
大小的內存空間,返回了一個指針arr
。因此,咱們能夠手動作這個步驟:code
typedef int integer; typedef integer * integer_pointer; integer_pointer * addIntegerToArr(integer_pointer p, ...) { integer_pointer *result = nil; if (p) { va_list args; int count = 1; integer_pointer current; va_start(args, p); while ((current = va_arg(args, integer_pointer))) { ++count; } va_end(args); result = (integer_pointer *)malloc((count) * sizeof(integer_pointer)); result[0] = p; va_start(args, p); current = va_arg(args, integer_pointer); for (int i = 1; i < count; i++) { result[i] = current; } va_end(args); } return (integer_pointer *)result; } int main(int argc, const char * argv[]) { integer a = 10; integer b = 11; integer_pointer pa = &a; integer_pointer pb = &b; integer_pointer *r = addIntegerToArr(pa, pb); integer_pointer num = r[1]; NSLog(@"%d", *num); return 0; }
裏面真正關鍵的一句代碼就是result = (integer_pointer *)malloc((count) * sizeof(integer_pointer));
,這樣咱們就開闢了一個內存空間,而且獲得一個integer_pointer *
類型的指針,因此能夠經過對這個指針的偏移,來操做這個空間中的integer_pointer
變量。對象
之因此result
看起來是一個數組,能夠用result[i]
這種寫法,就是由於上面的緣由。內存
因此,仍是要謹記,C語言中的數組,本質上就是指針加偏移。
雖然咱們是iOS開發者,可是畢竟C語言不能放,閒來無事能夠仿照runtime
中不少C語言特徵的寫法,來實現一些語言層面的學習。雖然上面所說的內容,對真正精通C/C++的高手來講,仍是太幼稚了,可是,思考的過程仍是很是有趣。何況,在上面這個練習中,還順手學習了一下可變參數的內容。
並沒什麼過高的技術含量,因此,此篇算做閒情而已。
更多內容歡迎訪問個人博客http://suntao.me