簡體   English   中英

將NSObject的所有屬性編碼為NSData

[英]Encode All Properties of NSObject to NSData

所以我是iOS的新手,但是我對簡單任務的復雜性感到困惑。 我正在嘗試在NSUserDefaults中存儲名為“ Vehicle”的自定義NSObject類。 顯然,這無法完成,因此我需要先將其編碼為NSDATA。 精細。

但這意味着我需要在解碼中對類的每個屬性進行編碼...

在我的車輛類中...

- (void) encodeWithCoder: (NSCoder *) coder
{
    [coder encodeInt: x  forKey: @"x"];
    [coder encodeInt: y  forKey: @"y"];
    [coder encodeInt: direction  forKey: @"direction"];

} // encodeWithCoder

- (id) initWithCoder: (NSCoder *) coder
{
    if (self = [super init]) {
        x = [coder decodeIntForKey: @"x"];
        y = [coder decodeIntForKey: @"y"];
        direction = [coder decodeIntForKey: @"direction"];
    }

    return (self);

} // initWithCoder

如果最終要在Vehicle類中添加一個新屬性,那么我也必須添加編碼和解碼邏輯。 這與使用CopyWithZone創建類的副本相同。 剩下3或4個區域,在其中向類添加新屬性可能會出錯。

我目前主要使用LabVIEW進行編程,我們有能力獲取一個類,並將其提供給編碼器,該編碼器將自動執行所有版本控制和屬性操作。

所以我想我的問題是:

  1. 在iOS中沒有聽說過嗎?
  2. 如果不可能,是否有辦法枚舉類中的所有屬性並編寫函數來自動執行此操作。

您可以使用Objective-C運行時來查找對象的所有屬性並對它們進行解碼,但是我不建議這樣做。 如果您願意,我可以為您創建一個簡單的示例。

編輯:這是一個示例:

#import <objc/runtime.h>

void decodePropertiesOfObjectFromCoder(id obj, NSCoder *coder)
{
    // copy the property list
    unsigned propertyCount;
    objc_property_t *properties = class_copyPropertyList([obj class], &propertyCount);

    for (int i = 0; i < propertyCount; i++) {
        objc_property_t property = properties[i];

        char *readonly = property_copyAttributeValue(property, "R");
        if (readonly)
        {
            free(readonly);
            continue;
        }

        NSString *propName = [NSString stringWithUTF8String:property_getName(property)];

        @try 
        {
            [obj setValue:[coder decodeObjectForKey:propName] forKey:propName];
        }
        @catch (NSException *exception) {
            if (![exception.name isEqualToString:@"NSUnknownKeyException"])
            {
                @throw exception;
            }

            NSLog(@"Couldn't decode value for key %@.", propName);
        }
    }

    free(properties);
}

void encodePropertiesOfObjectToCoder(id obj, NSCoder *coder)
{
    // copy the property list
    unsigned propertyCount;
    objc_property_t *properties = class_copyPropertyList([obj class], &propertyCount);

    for (int i = 0; i < propertyCount; i++) {
        objc_property_t property = properties[i];

        char *readonly = property_copyAttributeValue(property, "R");
        if (readonly)
        {
            free(readonly);
            continue;
        }

        NSString *propName = [NSString stringWithUTF8String:property_getName(property)];

        @try {
            [coder encodeObject:[obj valueForKey:propName] forKey:propName];
        }
        @catch (NSException *exception) {
            if (![exception.name isEqualToString:@"NSUnknownKeyException"])
            {
                @throw exception;
            }

            NSLog(@"Couldn't encode value for key %@.", propName);
        }
    }

    free(properties);
}

__attribute__((constructor))
static void setDefaultNSCodingHandler()
{
    class_addMethod([NSObject class], @selector(encodeWithCoder:), imp_implementationWithBlock((__bridge void *)[^(id self, NSCoder *coder) {
        encodePropertiesOfObjectToCoder(self, coder);
    } copy]), "v@:@");
    class_addMethod([NSObject class], @selector(initWithCoder:), imp_implementationWithBlock((__bridge void *)[^(id self, NSCoder *coder) {
        if ((self = [NSObject instanceMethodForSelector:@selector(init)](self, @selector(init))))
        {
            decodePropertiesOfObjectFromCoder(self, coder);
        }

        return self;
    } copy]), "v@:@");
}

這使您可以對任何公開了足以重建自身屬性的對象進行編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM