2012-03-14 6 views
3

プロパティにgetterとsetterというカスタム名が付いている場合は、プロパティ値を取得または設定するユーティリティを作成しています。 279 hereの完全な文脈を見ることができます。関連するスニペットはここにある:NSValueとNSInvocationを持つフリーとmalloc

- (id) getFrom:(id) object { 
    NSMethodSignature *methodSig = [[object class] instanceMethodSignatureForSelector:[self getter]]; 
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSig]; 
    [inv setSelector:[self getter]]; 
    [inv setTarget:object]; 
    [inv invoke]; 

    if ([self isObject]) { 
     id returnValue; 
     [inv getReturnValue:&returnValue]; 
     return returnValue; 
    } else { 
     void *buffer; 
     NSUInteger length = [methodSig methodReturnLength]; 
     buffer = (void *)malloc(length); 
     [inv getReturnValue:buffer]; 
     NSValue *value = [NSValue valueWithBytes:buffer objCType:[methodSig methodReturnType]]; 
     //FIXME: Memory leak for buffer! But if we free it, [value getValue:] is a dangling pointer. 
     //free(buffer) 
     return value; 
    } 
}  

問題は、プロパティがスカラのとき、私は(多くのキー値コーディングのような)NSValueを返したいということです。しかし、NSInvocationの戻り値は参照によって返され、the apple documentation(下部を参照)によれば、NSValueがまだ存在する間にスカラーに関連するメモリを解放することはできませんが、NSValueを返すのでいつメモリを解放するか分からない。

文書を間違って読んでいますか? NSValueはこれを何とか自動的に処理しますか?または、この状況でメモリを適切に解放するにはどうすればよいですか?

答えて

0

bufferを無料で登録する必要があります。 +valueWithBytes:objCType:は送信されたバッファをコピーするので、完了したらバッファを解放することができます。

はまた、必要に応じて、このように、ここにNSDataオブジェクトを使用することができます。

NSData *data = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES]; 

これはNSDataオブジェクトの割り当てが解除されたときに、そのバッファに作成したことを意味します。

int *buffer = malloc(sizeof(int)); 
buffer[0] = 50; 

NSValue *value = [NSValue valueWithBytes:buffer objCType:@encode(int)]; 

// sribble 'buffer' 
buffer[0] = 1000; 
free(buffer); 

int test = 1000; 
[value getValue:&test]; 

printf("%i", test); // outputs 50 
+0

ああ、私は間違ってリンゴのドキュメントを読んでいるに違いありません。ありがとう、それは確かに物事を簡素化する! – jagill

+0

@ジャッジル問題ありません!私は自分のテストアプリケーションを書くまで、個人的に答えを知らなかった! –

0

私はNSMutableData代わりのmalloc()を使用することをお勧めしたい:+valueWithBytes:objCType:コピーバッファこと

証明。あなたは、いくつかのメモリ

NSMutableData * dat = [NSMutableData dataWithLength:length]; 

を割り当て、それをあなたがmalloc D「チャンクが

void * buffer = [dat mutableBytes]; 

今すぐdatは、通常のココア参照カウントスキームの下でそれを置くメモリを、所有しているのと同じ方法を使用することができます。この時点から2つのうちの1つを実行できます。

このオブジェクトは短命であり、そのような配分をたくさんやっていない場合は、allocationsまたは類似呼ばNSMutableArray IVARがすべてNSMutableDataのインスタンスを保持することができ、及びその方法このオブジェクトがあるとき、彼らは解放されます割り当てが解除されます。

するのではなく、あなたがassociated objectsを使用して、必要に応じて、NSValue自体またはNSInvocationのいずれかにNSMutableDataの生活を結び付けることができますしたい場合:

dat_keyは近くの宣言 static変数、ある
objc_setAssociatedObject(value, &dat_key, dat, OBJC_ASSOCIATION_RETAIN); 

あなたが使用しているアドレス(ドキュメントが推奨する通り)。

アソシエータ(この場合はvalue)はデータオブジェクトを保持し、データオブジェクト自体の割り当てが解除されると解放します。

+0

NSValueはあなたが送信するバッファをコピーするので、完了したら単にバッファを解放するよりもずっと面倒です。 –

関連する問題