Objective c 可以从带有位字段的C结构创建NSValue吗?

Objective c 可以从带有位字段的C结构创建NSValue吗?,objective-c,c,cocoa,objective-c-runtime,bit-fields,Objective C,C,Cocoa,Objective C Runtime,Bit Fields,我试图执行以下操作,但是NSValue的创建方法返回nil。 结构中是否不支持C位字段 struct MyThingType { BOOL isActive:1; uint count:7; } myThing = { .isActive = YES, .count = 3, }; NSValue *value = [NSValue valueWithBytes:&myThing objCType:@encode(struct MyThingType)]

我试图执行以下操作,但是
NSValue
的创建方法返回
nil
。 结构中是否不支持C位字段

struct MyThingType {
    BOOL isActive:1;
    uint count:7;
} myThing = {
    .isActive = YES,
    .count = 3,
};

NSValue *value = [NSValue valueWithBytes:&myThing objCType:@encode(struct MyThingType)];
// value is nil here

首先也是最重要的一点,claptrap在他的评论中提出了一个非常好的观点:为什么要费心使用位字段说明符(主要用于进行微优化或在需要的地方手动添加填充位),然后将其全部封装到
NSValue
)的实例中。
这就像是买了一座城堡,但住在厨房里却不去清洗地毯

我不认为是这样,在苹果开发文档中快速慢跑。。。当涉及到位字段时,确实有几个问题需要考虑

我也刚刚发现,这解释了为什么位字段+
NSValue
不能很好地配合使用。
特别是在结构的
sizeof
可能导致
NSValue
读取结构中的数据的情况下。。。我们应该说不稳定的态度:
您创建的结构填充为8位。现在,这些位可以被读取为2
int
,或1
long
或其他什么。。。从我在链接页面上看到的情况来看,这不太可能发生。
因此,当您使用位字段时,
NSValue
基本上无法确定实际的类型。在出现歧义的情况下,假设int(大多数情况下宽度为4)并发生欠/溢出,您的手上会有一团乱

由于编译器对于成员的实际存储位置仍有一定的自由度,因此传递字符串化的typedef之类的内容(objCType:@encode(struct YourStruct),因为由于编译器优化等原因,您很有可能无法理解实际结构本身


我建议您简单地删除位字段说明符,因为应该支持结构…至少,上次我尝试时,具有简单基元类型的结构工作得很好。

您可以通过联合解决此问题。只需将结构放入联合,该联合具有另一个成员,该成员的类型由
NSValue
支持,并且其大小大于在你的例子中,这对于
long
来说是显而易见的

union _bitfield_word_union
{
  yourstructuretype bitfield;
  long plain;
};
通过使用在编译时计算大小的数组,可以使它更健壮地抵抗结构的大小调整。(请记住,
sizeof()
也是编译时运算符。)

然后,您可以将带有位字段的结构存储到union中,并读取
普通成员

union converter = { .bitfield = yourstructuretypevalue };
long plain = converter.plain;
使用此值创建实例。读取时必须使用相反的方法

我很确定,通过C99的技术修正,这成为了标准一致性(称为类型双关),因为您可以期望通过另一个成员值(
普通
)读取一个成员的值(
位域
)如果正在读取的成员至少与正在写入的成员一样大,则定义将其存储回。(在
普通
中可能有未定义的位9-31/63,但您不必关心它。)但它是真实世界的一致性


Dirty hack?也许吧。有人可能会称之为C99。但是,将位字段与
NSValue
结合使用听起来像是使用Dirty hack。

如果删除位字段说明符,它会起作用吗?有趣的问题,但我建议您根本不要使用位字段。无论如何,如果要增加将位字段放入计算机的开销,为什么还要麻烦使用位字段呢nto NSValue?@claptrap:goat point…我希望您不介意我将其添加到我的回答中。并非所有读取
@encode
的代码都能够处理
@encode
可以描述的所有类型。并非所有类型都可以由
@encode
正确描述。您可能希望使用NSData而不是NSValue来包装此结构。
union converter = { .bitfield = yourstructuretypevalue };
long plain = converter.plain;