gpt4 book ai didi

objective-c - 返回后使用 NSOperationQueue 延迟释放 malloc'd void*

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:41 26 4
gpt4 key购买 nike

我正在使用 NSInvocation 获取一些方法返回值,不幸的是我似乎有泄漏,但无法弄清楚如何释放 void* 我我正在分配,在我从 NSInvocation 返回它之后。

在下面的实现中,我试图用一个在下一个运行循环中执行的 block 来释放它,但是由于 returnBuffer 没有被分配,我遇到了崩溃。

为什么我不能释放 block 中的 returnBuffer,如果还没有分配它为什么要通过 returnBuffer!=NULL

这是一个与 IMP 调配有关的特殊方法,所以我不知道方法返回类型。将其放入 NSData 或其他内容将不起作用。

NSUInteger length = [[invocation methodSignature] methodReturnLength];
if(length!=0){
void* returnBuffer = (void *)malloc(length);
[invocation getReturnValue:&returnBuffer];
if(returnBuffer!=NULL){
void(^delayedFree)(void) = ^{ free(returnBuffer); };
[[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree];
}
return returnBuffer;
}
return nil;

回答多亏了 Josh 的 -[NSMutableData mutableBytes] 技巧

,它才能按以下方式工作
 NSUInteger length = [[invocation methodSignature] methodReturnLength];
if(length!=0){
NSMutableData * dat = [[NSMutableData alloc] initWithLength:length];
void* returnBuffer = [dat mutableBytes];
[invocation getReturnValue:&returnBuffer];
void(^delayedFree)(void) = ^{ [dat release]; };
[[NSOperationQueue mainQueue] addOperationWithBlock:delayedFree];
return returnBuffer;
}
return nil;

最佳答案

你可以从 NSMutableData 得到一个 void * ,就像你可以从 malloc() 得到一个,并且本质上把它变成一个实例变量,因此分配的生命周期与实例的生命周期相关联。我从 Mike Ash 得到这个技巧.我最近一直在做一些 NSInvocation 来调戏自己;这是在 NSInvocation 的类别中(当然,您应该为该方法使用自己的前缀):

static char allocations_key;
- (void *) Wool_allocate: (size_t)size {
NSMutableArray * allocations = objc_getAssociatedObject(self,
&allocations_key);
if( !allocations ){
allocations = [NSMutableArray array];
objc_setAssociatedObject(self, &allocations_key,
allocations, OBJC_ASSOCIATION_RETAIN);
}

NSMutableData * dat = [NSMutableData dataWithLength: size];
[allocations addObject:dat];

return [dat mutableBytes];
}

我不确定您发布的代码位于何处;如果您在自己的自定义类中,则无需处理关联的对象位——只需将 allocations 设为 ivar。

将其绑定(bind)到您的代码中:

NSUInteger length = [[invocation methodSignature] methodReturnLength];
if(length!=0){
void* returnBuffer = [self Wool_allocate:length];
[invocation getReturnValue:&returnBuffer];
return returnBuffer;
}
return nil;

如果您使用关联的对象路由,allocations 数组将在该实例被释放时被释放。否则,只需将 [allocations release] 放入您的 dealloc

此外,要回答您提出的问题,而不仅仅是解决问题:free() 不会对您未从 malloc()< 获得的任何指针进行操作。当指针在 Block 中使用时,我很确定它被复制了,所以你最终得到了 另一个 指针——仍然指向相同的内存,但是 free() 不认为它拥有。因此,您会收到有关未分配它的错误。

关于objective-c - 返回后使用 NSOperationQueue 延迟释放 malloc'd void*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9288253/

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