iOS中使用结构体与位域,大小端数据转换

如何在iOS中使用结构体数据类型

在定义结构体时,如果不涉及到OC中的对象时,可以直接将结构体当作成员变量属性使用,一旦在结构中定义了OC中的对象,编译会报错,提示“ARC时禁止在结构体中定义OC的对象”,主要原因在于ARC无法管理结构体中的OC对象的生命周期以内存。可以从以下几个方面分析:

  • ARC在是编译器特性,编译时在合适的位置插入对象的内存管理代码。由于标准的C语言结构体struct没有析构函数,编译器无法在合适的位置插入内存管理代码,从而导致内存泄漏。因此在ARC项目中,如果没有做特殊处理,在结构体中不能声明OC对象,除非明确指出放弃对该对象的内存管理权限,例如将对象定义为 __unsafe_unretain
  • 在定义结构体时,成员变量全部用基本数据类型,不引入OC对象
  • ARC项目不支持,但是非ARC项目支持,可以在定义结构体的编译文件上加上 -fno-objc-arc编译选项
  • 在定义对象时,声明放弃对该对象的内存管理权限,类似于 __unsafe_unretain UIView *customView ,尽管如此,这种做法有可能使得在引用对象时,该对象已经释放,导致莫名的错误
  • 可以创建一个类来代替结构体

如何在结构体中使用位域

位域定义如下:

typedef struct {
    unsigned int second: 6;
    unsigned int minute: 6;
    unsigned int hour: 5;
    unsigned int day:5;
    unsigned int month :4;
    unsigned int year: 6;
}testStruct;

位域的定义形式为:类型说明符号 位域名:位域长度
这里的位域长度单位是 bit 位,而不是字节数,正因为如此,在某些内存要求比较高的场景中,通过位域可以节省一定的内存。
注意:位域是从低位向最高位分配内存的

大端数据与小端数据

大端对齐数据(网络顺序)

数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。

小端对齐数据(主机顺序)

数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。(简单的来说就是反过来存放数据了)

在iOS中可以通过 ntohl(x) 与 htonl(x) 函数实现大小端数据之间的转换,net to host long(返回值) 或者 host to net long(返回值)

- (NSData *)intNetToHostdata:(int)i {
    //  网络到主机顺序 (转换成小端数据)
    int j = ntohl(i);
    NSData *data = [NSData dataWithBytes:&j length:sizeof(i)];
    return data;
}

参考链接:iOS中位域(位段)的简单使用

你可能感兴趣的:(iOS移动开发)