2011-07-30 14 views
6

を解放する正しい方法私はこの機能を使用してunsigned char型のポインタを作成します。CとObjective-C - 私のアプリにunsigned char型ポインタ

- (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されたメモリを解放できますか? deallocでプロパティを解放しようとすると、exc_bad_accessエラーが発生します。私はここで基本的なCや目標-Cのコンセプトが欠けているように感じます。すべての助けに感謝します。

+0

どのようにプロパティをfree'ingですか? – iandotkelly

+1

各アロケータには、割り当てられたオブジェクトを解放するためのペア解除されたアロケータがあります。 ['malloc'](http://linux.die.net/man/3/malloc)のマニュアルページを見てください - しかしあなたの特定のプラットフォームに関連するドキュメントを見つけるのに最適です - 何を使うべきかを説明します;-) –

+0

私は正しいように見えない無料(プロパティ)を試みたが、とにかくそれを行った。 –

答えて

6

目的-cでmalloc/freeを使用する場合の安全性に関する十分な議論があります。here

あなたがmalloc()のメモリを正しく解放する限り、となります。

私は個人的にNSMutableDataまたはNSMutableArrayを使用する方が簡単だと思います。究極のパフォーマンスが必要ない場合は、C malloc/free文を直接使用しません。問題のこの種の周り

+0

それは、実際に私の自由の使用と無関係だった答えに私を導いてくれました。フリー(self.property)を使用する。間違っていた* facepalm *。私は自由(不動産)を試みた。それはうまく動作します。将来私はmallocの面倒を避けるためにNSDataを使用すると信じています。 –

4

一つの方法は、あなたが、あなたのデアロケータでMYDATAを解放することができ

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

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

を置き換えることができますので、NSMutableDataを使用することです。あなたはこれは、あなたのMYDATAはイベントループの期間を中心に保たれている、あなたが原因でも、リターンへgetRawDataメソッドの戻り値の型を変更することができますを意味します

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

を行うことができます

alternativly NSMUtableDataまたはNSDataを使用し、コードの他の部分で保持できるようにすると、コード内で生のバイトを返す唯一の時間は、返すオブジェクトの寿命の間に利用できることがわかっている場合です。私は所有者のクラスを保持することができますデータを保持する必要があります。

Appleはしばしば

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

パターンを使用して、あなたは現在の自動解放プールサイクルを超えるバイトが必要な場合は、それをコピーする必要がありますことを文書化します。

+0

これは同じ問題ではないのですが、今は生ポインタの代わりにオブジェクトを使用していますか?オブジェクトは解放されなければならず、生ポインタは解放されなければならない。どちらの場合も、廃棄することができるときはかなり明確になるように設計する必要があります。 –

+0

オブジェクトを扱う方が簡単です。これは、retain/releaseルールに固執できるからです。メソッドから生のバイトを返す場合、メソッドの呼び出し側がメモリを正しく管理していること、メソッドの呼び出し側が返されたバイトに関心がない場合はどうなるでしょうか。バイトがプライベートメソッドから返された場合、あなたは何でも好きなことをすることができますが、それがパブリックインターフェイスの一部であれば、馬鹿な証拠を作るので、6ヶ月前に書いたメソッドを覚えておく必要はありません通常のやり方で動作します。単純なルールセットに従う方がずっと簡単です。 –

+0

だから私は**メモリ**を返すことはありません。私は呼び出し元にどのくらいの大きさでなければならないかを伝え、呼び出し元はあなたに割り当てるバッファを渡すことができます。あなたはバッファを埋めるだけです。そうすれば、オーナーシップははるかに明確になります。 –

関連する問題