gpt4 book ai didi

objective-c - NSData initWithBytesNoCopy :length:freeWhenDone: 的行为

转载 作者:太空狗 更新时间:2023-10-30 03:42:25 27 4
gpt4 key购买 nike

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

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

如果我从 buffer 创建一个 NSData 后修改它会发生什么? NSData 会反射(reflect)我对 buffer 所做的更改吗?

我可以保证当我想修改buffer时,sharedData不会被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 = //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);

最佳答案

initWithBytesNoCopy: 将有效地在现有缓冲区周围创建一个 NSData 包装器;所以是的,通过 [sharedData bytes] 访问的内容将看到您所做的任何更新。

当然,它不会链接从 NSData 实例创建的其他对象,因此例如 [NSImage initWithData:sharedData] 可以为NSImage 实例,它不会反射(reflect)任何更改。

此外,使用 freeWhenDone:YES 时,NSData 将在删除最后一个引用时销毁缓冲区,因此请注意 =)


因此,鉴于 NSData 实际上是 malloc() 分配的薄包装,是的,它会反射(reflect)对该内存所做的更改(由任何进程);但是因为它会调用 free(),所以用它来包装用 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.

关于objective-c - NSData initWithBytesNoCopy :length:freeWhenDone: 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8691997/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com