C и Objective-C - правильный способ освободить указатель без знака - PullRequest
6 голосов
/ 30 июля 2011

В моем приложении я создаю беззнаковый указатель на символ с помощью этой функции:

- (unsigned char*)getRawData
{
// First get the image into your data buffer
CGImageRef image = [self CGImage];
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);

CGContextSetBlendMode(context, kCGBlendModeCopy);

CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), image);
CGContextRelease(context);

// Now your rawData contains the image data in the RGBA8888 pixel format.

return rawData;
}

А в другом классе я назначаю этому указателю свойство следующим образом: self.bitmapData = [image getRawData];

Где в этом процессе я могу освободить память malloc'd? Когда я пытаюсь освободить свойство в dealloc, выдается ошибка exc_bad_access. Я чувствую, что мне здесь не хватает фундаментальной концепции c или target-c. Вся помощь приветствуется.

Ответы [ 2 ]

6 голосов
/ 30 июля 2011

Хорошая дискуссия о безопасности использования malloc / free в файле target-c здесь .

До тех пор, пока вы правильно освободите () память, которую вы используете malloc (), должно не быть проблемой.

Лично я считаю, что использовать NSMutableData или NSMutableArray проще. Если вам не нужна максимальная производительность, я бы не использовал операторы C malloc / free напрямую.

4 голосов
/ 30 июля 2011

Одним из способов решения этой проблемы является использование NSMutableData, поэтому вы можете заменить

unsigned char *rawData = malloc(height * width * 4);

с

myData = [[NSMutableData alloc] initWithCapacity:height * width * 4];
unsigned char *rawData = myData.mutableBytes;

затем вы можете освободить myData в вашем деаллокаторе.

альтернативно вы можете сделать

myData = [NSMutableData dataWithCapacity:height * width * 4];

Это будет означать, что ваши myData будут храниться в течение всего цикла обработки событий, вы можете даже изменить тип возвращаемого значения getRawData метода для возврата NSMUtableData или NSData, и таким образом он может быть сохранен другими частями вашего кода, единственный раз, когда я возвращаю необработанные байты в моем коде, если я знаю, что он будет доступен для жизни объекта, который его возвращает, таким образом, если мне нужно удерживать Данные я могу сохранить класс владельца.

Apple будет часто использовать

myData = [[NSMutableData alloc] initWithCapacity:height * width * 4];
unsigned char *rawData = myData.mutableBytes;

, а затем задокументируйте, что если вам нужны байты за пределами текущего цикла пула автоматического выпуска, вам придется скопировать его.

...