亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

獲取Objective-C中的對象屬性列表

獲取Objective-C中的對象屬性列表

慕標5832272 2019-08-15 15:13:43
獲取Objective-C中的對象屬性列表如何在Objective-C中獲取給定對象屬性的列表(以NSArray或的形式NSDictionary)?想象一下下面的場景:我已經定義了一個只擴展的父類NSObject,它將a NSString,a BOOL和一個NSData對象作為屬性。然后我有幾個擴展這個父類的類,每個類都添加了很多不同的屬性。有沒有什么方法可以在父類上實現一個遍歷整個對象的實例方法,然后返回NSArray每個(子)類屬性的一個,因為NSStrings它不在父類上,所以我以后可以使用這些NSString對于KVC?
查看完整描述

3 回答

?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

我自己設法得到了答案。通過使用Obj-C運行時庫,我可以按照我想要的方式訪問屬性:

- (void)myMethod {
    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];
        const char *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithCString:propName
                                                                encoding:[NSString defaultCStringEncoding]];
            NSString *propertyType = [NSString stringWithCString:propType
                                                                encoding:[NSString defaultCStringEncoding]];
            ...
        }
    }
    free(properties);}

這要求我制作一個'getPropertyType'C函數,它主要取自Apple代碼示例(現在不能記住確切的來源):

static const char *getPropertyType(objc_property_t property) {
    const char *attributes = property_getAttributes(property);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T') {
            if (strlen(attribute) <= 4) {
                break;
            }
            return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
        }
    }
    return "@";}


查看完整回答
反對 回復 2019-08-15
?
明月笑刀無情

TA貢獻1828條經驗 獲得超4個贊

它實際上并不總是以0結束字符串。這可能會導致意外的結果,比如在嘗試將其轉換為UTF8時崩潰(我實際上有一個非常令人討厭的崩潰因為這個。很有趣的調試它^^)。我通過實際從屬性獲取NSString然后調用cStringUsingEncoding來修復它:這就像現在的魅力。(也適用于ARC,至少對我而言)

所以這是我現在的代碼版本:

// PropertyUtil.h#import @interface PropertyUtil : NSObject+ (NSDictionary *)classPropsFor:(Class)klass;@end// PropertyUtil.m#import "PropertyUtil.h"#import <objc/runtime.h>@implementation PropertyUtilstatic const char *getPropertyType(objc_property_t property) {
    const char *attributes = property_getAttributes(property);
    //printf("attributes=%s\n", attributes);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T' && attribute[1] != '@') {
            // it's a C primitive type:
            /*
             if you want a list of what will be returned for these primitives, search online for
             "objective-c" "Property Attribute Description Examples"
             apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
             */
            NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
            return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
        }
        else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
            // it's an ObjC id type:
            return "id";
        }
        else if (attribute[0] == 'T' && attribute[1] == '@') {
            // it's another ObjC object type:
            NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
            return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
        }
    }
    return "";}+ (NSDictionary *)classPropsFor:(Class)klass{
    if (klass == NULL) {
        return nil;
    }

    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(klass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            [results setObject:propertyType forKey:propertyName];
        }
    }
    free(properties);

    // returning a copy here to make sure the dictionary is immutable
    return [NSDictionary dictionaryWithDictionary:results];}@end


查看完整回答
反對 回復 2019-08-15
  • 3 回答
  • 0 關注
  • 702 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號