Вы можете получить void *
из NSMutableData
, точно так же, как вы можете malloc()
, и, по сути, превратить его в переменную экземпляра, так что время жизни выделения будет привязано к времени жизни экземпляра. Я получил этот трюк от Майка Эша . В последнее время я занимался обезьяной. это относится к категории 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
иваром.
Свяжите это в свой код:
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()
. Когда указатель используется в блоке, я почти уверен, что он скопирован, так что в итоге вы получаете другой указатель - все еще указывающий на ту же память, но ту, которую free()
не считает он владеет. Таким образом, вы получаете ошибку о том, что вы ее не разместили.