本文共 3903 字,大约阅读时间需要 13 分钟。
在 Core Foundation 中,函数的名称中含有 create
或 copy
的,那么变量对返回对象为强引用,如果是含有 get
的函数返回的对象,则对其为弱引用。
如此,需要根据具体情况,使用 CFRetain
和 CFRelease
对变量进行持有或释放,从而修改对象的引用计数。除此之外,还可以通过 CFGetRetainCount
查看对象的引用计数值。
对于参数的传递或对象所拥有的变量,应当认为参数在函数中被持有,对象同样强引用相关变量,因为使用过程中,变量不应被销毁。
在 Core Foundation 中,对于诸如 int
、float
等基本类型,简单的赋值操作即为拷贝。但是对于对象而言,简单的赋值只是引用的拷贝。可以使用诸如 CFStringCreateCopy
的函数进行拷贝。但是,这种拷贝只是浅拷贝,如集合等包含有其他对象的复合对象,并不会拷贝其自身引用的对象。所以要对自身持有的对象进行深层次的拷贝,可以使用诸如 CFPropertyListCreateDeepCopy
的函数,还可以自定义深拷贝函数,只是要注意避免循环拷贝的情况。
在微处理器中,处理多字节的数据时,有两种存储方式。
大端字节排序,数据高位在底地址,数据低位在高地址。即按数据的正常书写方向开始,从低到高进行编址。
小端字节排序,数据高位在高地址,数据低位在低地址。即从数据的低位开始到高位,将其依次存储到低地址到高地址。
一般而言,字符串的传递不需要考虑字节顺序,但对于字(2字节)或双字(4个字节)等长度的数据而言,就需要考虑字节的传输顺序问题。所以,数据交换双方需要知道数据本身的类型、字节存储顺序以及处理器本身处理数据的字节顺序。
CFByteOrder.h
中提供了一些处理字节顺序的函数,但是只适用于 OS X
系统。
其中提供了几个强制变更字节顺序的方法 CFSwapInt16(uint16_t arg), CFSwapInt32(uint32_t arg), CFSwapInt64(uint64_t arg)
。
还提供了根据客户机的字节顺序处理方式,来判断自行是否需要变更顺序的方法。
可以分为四类,以2个字节长度为例,方法如下:
uint16_t CFSwapInt16BigToHost(uint16_t arg)
uint16_t CFSwapInt16HostToBig(uint16_t arg)
uint16_t CFSwapInt16LittleToHost(uint16_t arg)
uint16_t CFSwapInt16HostToLittle(uint16_t arg)
这四类共12个函数,在使用时,会根据需要进行字节顺序的变换。
此外,还定义了下面两个结构体,用来转换浮点型的数据,从而达到传输过程中忽略字节顺序的目的。
typedef struct {uint32_t v;} CFSwappedFloat32;typedef struct {uint64_t v;} CFSwappedFloat64;
同样的,需要使用下面的方法来进行类型的转换。
CFSwappedFloat32 CFConvertFloat32HostToSwapped(Float32 arg)
Float32 CFConvertFloat32SwappedToHost(CFSwappedFloat32 arg)
CFSwappedFloat64 CFConvertFloat64HostToSwapped(Float64 arg)
Float64 CFConvertFloat64SwappedToHost(CFSwappedFloat64 arg)
CFSwappedFloat32 CFConvertFloatHostToSwapped(float arg)
float CFConvertFloatSwappedToHost(CFSwappedFloat32 arg)
CFSwappedFloat64 CFConvertDoubleHostToSwapped(double arg)
double CFConvertDoubleSwappedToHost(CFSwappedFloat64 arg)
CFAllocatorRef 是系统定义的 __CFAllocator
结构体的别名,在 Core Foundation 中,使用函数创建对象时需要传递该类型的参数,表示内存申请和释放的方式。
框架本身提供了一些该类型的常量,以供大家使用。
常量名 | 说明 |
---|---|
kCFAllocatorDefault | 同 NULL 同义,表示使用当前线程中默认的 CFAllocatorRef 变量进行内存管理 |
kCFAllocatorSystemDefault | 系统默认的内存管理方式 |
kCFAllocatorMalloc | 使用 malloc(), realloc(), free() 等方法实现内存管理 |
kCFAllocatorMallocZone | 使用 malloc_default_zone() 返回的默认内存区域 |
kCFAllocatorNull | 不对相关变量的内存进行管理 |
kCFAllocatorUseContext | 表示在使用 CFAllocatorCreate() 创建自定义的 CFAllocatorRef 变量时,该变量本身也使用 CFAllocatorContext 变量中的相关方法进行内存的管理 |
可以使用 CFAllocatorSetDefault(CFAllocatorRef allocator)
函数修改当前线程中的默认内存管理方式,但是应当先用 CFAllocatorGetDefault()
函数获取原默认方式,在使用完毕后,设置回原方式。
实际上,每个 CFAllocatorRef 变量都有相关联的 CFAllocatorContext 变量保存着内存管理的具体操作,可以使用下面的函数获取某个变量的内存管理变量 CFAllocatorRef ,进而获取相关的管理函数的持有者 CFAllocatorContext 类型的结构体。
CFAllocatorRef CFGetAllocator(CFTypeRef cf);void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context);
CFAllocatorContext 除了保存有版本信息、额外信息外,还持有内存管理的相关方法。
typedef const void * (*CFAllocatorRetainCallBack)(const void *info);typedef void (*CFAllocatorReleaseCallBack)(const void *info);typedef CFStringRef (*CFAllocatorCopyDescriptionCallBack)(const void *info);typedef void * (*CFAllocatorAllocateCallBack)(CFIndex allocSize, CFOptionFlags hint, void *info);typedef void * (*CFAllocatorReallocateCallBack)(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);typedef void (*CFAllocatorDeallocateCallBack)(void *ptr, void *info);typedef CFIndex (*CFAllocatorPreferredSizeCallBack)(CFIndex size, CFOptionFlags hint, void *info);typedef struct { CFIndex version; void * info; CFAllocatorRetainCallBack retain; CFAllocatorReleaseCallBack release; CFAllocatorCopyDescriptionCallBack copyDescription; CFAllocatorAllocateCallBack allocate; CFAllocatorReallocateCallBack reallocate; CFAllocatorDeallocateCallBack deallocate; CFAllocatorPreferredSizeCallBack preferredSize;} CFAllocatorContext;
在使用 CFAllocatorContext 来自定义 CFAllocatorRef 时,CFAllocatorAllocateCallBack 函数是必须要提供的。除此之外,还可以实现内存释放、重新申请、内存大小等函数。
详细可参见。
转载地址:http://ivdws.baihongyu.com/