Bry*_*hen 6 cocoa objective-c nsdata
我想要一个修复长度可变内容共享数据缓冲区,这是我如何创建它:
void *buffer = malloc(length);
// initialize buffer content
NSData *sharedData = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES]
Run Code Online (Sandbox Code Playgroud)
如果我buffer从中创建NSData后进行修改会发生什么?NSData会反映我做的改变buffer吗?
sharedData当我想修改时,我可以保证不会得到dealloc buffer.
这就是我实际想要使用它的方式:
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);
}
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
这initWithBytesNoCopy:将有效地创建一个NSData围绕现有缓冲区的包装器; 所以是的,通过访问的东西[sharedData bytes]会看到你做的任何更新.
当然,它不会链接从NSData实例创建的其他对象,因此例如,[NSImage initWithData:sharedData]可以为实例创建副本NSImage,这不会反映任何更改.
此外,与freeWhenDone:YES该NSData会破坏当最后一个引用被移除的缓冲,所以看出来那个=)
所以,鉴于它NSData实际上是一个malloc()分配的瘦包装,是的,它将反映对该内存的更改(通过任何进程); 但是因为它会调用free()它,所以使用它来包装另一个方式(mach_vm_allocate)创建的缓冲区是一个坏主意freeWhenDone:YES.
如果你真的不需要使用自定义分配器(为什么?),我认为你会更好:
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.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2738 次 |
| 最近记录: |