如何使用NSCoding存储NSUInteger? [英] How to store a NSUInteger using NSCoding?

查看:166
本文介绍了如何使用NSCoding存储NSUInteger?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 NSCoding 协议存储 NSUInteger ,因为<$ c上没有方法$ c> NSCoder like -encodeUnsignedInteger:(NSUInteger)anInt forKey:(NSString *)aKey 就像 NSInteger

How do I store a NSUInteger using the NSCoding protocol, given that there is no method on NSCoder like -encodeUnsignedInteger:(NSUInteger)anInt forKey:(NSString *)aKey like there is for NSInteger?

以下工作,但这是最好的方法吗?这不需要创建对象。

The following works, but is this the best way to do this? This does needlessly create objects.

@interface MYObject : NSObject <NSCoding> {
    NSUInteger count;
}  

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:[NSNumber numberWithUnsignedInteger:count] forKey:@"count"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self != nil) {
        count = [[decoder decodeObjectForKey:@"count"] unsignedIntegerValue];
    }
    return self;
}


推荐答案

问题是 NSUInteger 可能不是与 unsigned int 相同的大小。在许多(如果不是大多数现在)Mac OS X机器上, NSUInteger 将是 unsigned long 两倍大。另一方面,一个键控的档案器应该处理这个没有问题,因为它构建一个字典。

The problem is that NSUInteger may not be the same size as an unsigned int. On many (if not most by now) Mac OS X machines, NSUInteger will be an unsigned long, which will be twice as big. On the other hand, a keyed archiver should handle that without a problem, since it builds a dictionary.

更复杂的事情是NSCoder没有任何方法以处理无符号类型。我不能想到这将如何导致任何数据丢失,但它将需要一些丑陋的演员,加上它只是感觉很脏。

Further complicating matters is the fact that NSCoder doesn't have any methods to deal with unsigned types. I can't think of how this would cause any data loss, but it would require some ugly casts, plus it just feels dirty.

如果你想坚持一个无符号类型,最简单的方法是对原始字节进行编码(最好使用 htonl ntohl 使用 encodeBytes:length:forKey:在最大类型( unsigned long long decodeBytesForKey:returnedLength:。为了最大程度的安全,你应该检查你解码的长度,并转换指针(或使用联合)来提取正确大小的类型。

If you want to insist upon an unsigned type, the simplest way would be to encode the raw bytes (preferably in network byte order using htonl and ntohl) in the largest type available (unsigned long long) using encodeBytes:length:forKey: and decodeBytesForKey:returnedLength:. For maximum safety, you should check the length of what you decoded and cast the pointer (or use a union) to extract the correct-sized type.

是该值将在输出中表示为数据,而不是整数。这主要是有关的,只有当有人决定读入原始plist数据为您的档案,而不是像你一样使用键控unarchiver,甚至只有他们。其他情况下,如果苹果(或你)应该切换到一个具有更大的整数类型的架构,类型的位大小不是一个二的幂(有至少一个旧平台,一个字是24位)或具有不寻常布局的类型(不大或小端序)。

The drawback of this is that the value will be represented in the output as data, not an integer. This mainly matters only if somebody decides to read in the raw plist data for your archive instead of using the keyed unarchiver like you do, and even then only to them. The other cases where it might matter is if Apple (or you) should ever switch to an architecture that has even larger integer types, types whose size in bits is not a power of two (there's at least one old platform where a word was 24 bits), or types with an unusual layout (not big- or little-endian).

对于您的NSNumber解决方案:您可能想要破解列表编辑器,看看它发出了什么。如果输出包含整数元素,则它与使用 encodeInteger:forKey:相同。如果输出包含数据元素,那么它与上面提到的解决方案相同。要彻底,您应该检查您支持的每个架构的输出。

As for your NSNumber solution: You might want to crack open your archive in Property List Editor and see what it emitted. If the output contains an integer element, then it's the same as using encodeInteger:forKey:. If the output contains a data element, then it's the same as the solution I mentioned above. To be thorough, you should check the output from every architecture you support.

这篇关于如何使用NSCoding存储NSUInteger?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆