NSData的行为initWithBytesNoCopy:length:freeWhenDone: [英] Behavior of NSData initWithBytesNoCopy:length:freeWhenDone:

查看:1395
本文介绍了NSData的行为initWithBytesNoCopy:length:freeWhenDone:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个固定长度的可变内容共享数据缓冲区,这是如何创建它:

  void * buffer = malloc(length); 
//初始化缓冲区内容
NSData * sharedData = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES]

在我创建了一个NSData之后,如果我修改 buffer 会发生什么? NSData会反映我对 buffer ?

所做的更改

我可以保证 sharedData 当我要修改 buffer 时,不会得到dealloc。



想要使用它:






  void * my_alloc(CFIndex allocSize,CFOptionFlags hint, void * info){return NULL;} 
void my_dealloc(void * ptr,void * info){
mach_vm_deallocate(mach_task_self(),(mach_vm_address_t)ptr,(size_t)info);
}






  size_t length = //一些数字
mach_vm_address_t buffer;
mach_vm_allocate(mach_task_self(),& buffer,length,VM_FLAGS_ANYWHERE);
//做某些缓冲,例如使用mach RPC传递给其他进程,并期望其他进程将修改内容
CFAllocatorContext context = {0,(void *)length,NULL,NULL, my_alloc,NULL,my_dealloc,NULL};
CFAllocatorRef allocator = CFAllocatorCreate(NULL,& context);
CFDataCreateWithBytesNoCopy(NULL,(const UInt8 *)buffer,length,allocator);
initWithBytesNoCopy: code>将有效地在现有缓冲区周围创建一个 NSData 包装;所以是的,通过 [sharedData bytes] 访问的任何内容都会看到您所做的更新。



当然,没有链接从 NSData 实例创建的其他对象,因此例如 [NSImage initWithData:sharedData] NSImage 实例创建副本,这将不会反映任何更改。



此外, $ c> freeWhenDone:YES NSData 会在删除最后一个引用时破坏缓冲区,所以请留意=)






因此,由于 NSData 实际上是< c $ c> malloc() allocation,yes它将反映对该内存的更改(由任何进程);但是它会调用 free(),它是一个坏主意,使用它包装另一种方式创建的缓冲区( mach_vm_allocate )with freeWhenDone:YES



如果你真的不需要使用自定义分配器(为什么?),我想你会更好的:

  NSMutableData * sharedData = [NSMutableData dataWithCapacity:length] ; 
//`dataWithLength:`将首先完全分配和清零缓冲区,如果你喜欢
void * buffer = [sharedData mutableBytes];
//对'buffer`,mach RPC等做某事
// 3:利润。


I want to have a fix length mutable content shared data buffer and that is how do I create it:

void *buffer = malloc(length);
// initialize buffer content
NSData *sharedData = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES]

What happen if I modify buffer after I created a NSData from it? Will NSData reflect the change I did to buffer?

I can guaranty that sharedData will not get dealloc when I want to modify buffer.

This is how I actually want to use it:


void *my_alloc(CFIndex allocSize, CFOptionFlags hint, void *info) {return NULL;}
void my_dealloc(void *ptr, void *info) {
    mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)ptr, (size_t)info);
}


size_t length = //some number
mach_vm_address_t buffer;
mach_vm_allocate(mach_task_self(), &buffer, length, VM_FLAGS_ANYWHERE);
// do something to buffer, for example pass to other process using mach RPC and expect other process will modify the content
CFAllocatorContext context = {0, (void *)length, NULL, NULL, NULL, my_alloc, NULL, my_dealloc, NULL};
CFAllocatorRef allocator = CFAllocatorCreate(NULL, &context);
CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)buffer, length, allocator);

解决方案

The initWithBytesNoCopy: will effectively create an NSData wrapper around the existing buffer; so yes, things accessing through [sharedData bytes] will see any updates you make.

Of course, it does nothing to link other objects which are created from the NSData instance, so for instance an [NSImage initWithData:sharedData] may make a copy for the NSImage instance, which won't reflect any changes.

Also, with freeWhenDone:YES the NSData will destroy the buffer when the last reference is removed, so look out for that =)


So, given that the NSData is effectively a thin wrapper around a malloc() allocation, yes it will reflect changes made to that memory (by any process); but as it will call free() on it, it's a bad idea to use it to wrap a buffer created another way (mach_vm_allocate) with freeWhenDone:YES.

If you don't really-really need to use a custom allocator (why?), I think you'd be better off with:

NSMutableData* sharedData = [NSMutableData dataWithCapacity:length];
// `dataWithLength:` will fully allocate and zero the buffer first, if you prefer
void* buffer = [sharedData mutableBytes];
// do something to `buffer`, mach RPC, etc.
// 3: profit.

这篇关于NSData的行为initWithBytesNoCopy:length:freeWhenDone:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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