Cocoaオブジェクトのインターフェイスブロックで、ac配列をインスタンス変数(たとえば、int arr [256])として宣言したいと思います。@propertyがc配列をサポートしていないことは知っていますが、c配列のゲッターとセッターを手動で追加する方法と、どこに割り当てて解放する必要がありますか?
任意の入力をいただければ幸いです。int値にアクセスするためにNSMutableArrayを使用したくありません。
Cocoaオブジェクトのインターフェイスブロックで、ac配列をインスタンス変数(たとえば、int arr [256])として宣言したいと思います。@propertyがc配列をサポートしていないことは知っていますが、c配列のゲッターとセッターを手動で追加する方法と、どこに割り当てて解放する必要がありますか?
任意の入力をいただければ幸いです。int値にアクセスするためにNSMutableArrayを使用したくありません。
構造体を使用して配列をまとめることができます。これはおそらく、配列を割り当てによってコピーできるようにする1つの例外です。このアプローチの利点は、メモリを明示的に割り当てたり解放したりする必要がないことです。
typedef struct
{
int data[256];
} MyInts;
@interface MyClass : NSObject
{
MyInts ints;
}
- (MyInts) ints;
- (void) setInts:(MyInts) someInts;
@end
@implementation MyClass
- (MyInts) ints
{
return ints;
}
- (void) setInts:(MyInts) someInts
{
ints = someInts;
}
@end
int main(void)
{
MyInts ints = {{0}};
ints.data[4] = 345;
ints.data[5] = 123;
ints.data[6] = 101;
MyClass *someObj = [[MyClass alloc] init];
[someObj setInts:ints]; // provide the ints to the object
[someObj mutateTheInts]; // have object do something with them
ints = [someObj ints]; // get them back
return 0;
}
どこに割り当てて解放すればよいですか?
さて、あなたはそれを他のインスタンス変数と同じ場所に割り当てて解放します:ininit
とdealloc
。秘訣は、andの代わりにandを使用する必要があるmalloc
というfree
ことretain
ですrelease
。
プロパティについては、宣言することができます。独自のアクセサーとミューテーターを作成するだけです。
また、この目的のために、C配列はポインターのようなものであることを思い出してください。
そうは言っても、あなたはこのようなことをするかもしれません:
@interface MyClass : NSObject
{
int *arr;
}
@property int *arr;
@end
@implementation MyClass
#import <stdlib.h>
@dynamic arr;
- (id)init
{
if ((self = [super init])) {
arr = malloc(sizeof(int) * 256);
}
return self;
}
- (void)dealloc
{
free(arr);
[super dealloc];
}
- (int *)arr
{
// Return a copy -- don't want the caller to deallocate
// our instance variable, or alter it without our knowledge!
// Also note that this will leak unless the caller releases it.
int *arrCpy = malloc(sizeof(int) * 256);
memcpy(arrCpy, arr, sizeof(int) * 256);
return arrCpy;
}
- (void)setArr:(int *)anArr
{
if (arr != anArr) {
free(arr);
// Again, copy the data so that the caller can't
// change the values of specific ints without
// out knowledge.
int *anArrCpy = malloc(sizeof(int) * 256);
memcpy(anArrCpy, anArr, sizeof(int) * 256);
arr = anArrCpy;
}
}
あなたが行うことができるいくつかのより良いエラーチェックがあり、コードは少しきれいになる可能性がありますが、それが要点です。
CoreFoundationデータ型を使用することもできます。これは基本的にCのプリミティブと構造体です。メモリ管理は少し簡単ですが、要求した「ストレートC」intでもありません。
ただし、正直なところ、NSNumberオブジェクトのNSArrayを使用する方がよいと思います。メモリ管理ははるかに簡単で、おそらく他のObjective-Cフレームワークとの互換性が高くなります。また、Cocoaは64ビット環境と32ビット環境、およびデータ型のエンディアンを考慮しているため、プラットフォームに依存しません。少なくとも、intの代わりにNSIntegerを使用する必要があります。
それらを宣言することはできますが、C配列の「セッター」などはありません。Cで設定することはできず、インデックスに値を割り当てるだけです。ポインタ用のゲッターとセッターを使用することもできますが、それに答える必要のあるメモリ管理の質問が多数発生します。
intの配列が必要で、それを管理したり、オブジェクト自体とは別に割り当てて解放したりする必要がない場合は、次のように宣言します。
int arr[256];
@interface宣言で、オブジェクトには256intの余地があるインスタンス変数があります。配列のint要素にゲッターまたはセッターが必要な場合は、それらを手動で宣言して書き込む必要があります(プロパティの前の昔ながらの方法)。
- (int)myElementOfArrAtIndex:(int)index {
if (index >= 0 && index <= 255) {
return (arr[index]);
} else {
// error handler
}
}
等
オブジェクトとは別に配列のメモリを管理する場合を除いて、ポインタを宣言する必要はありません(たとえば、配列を保持してオブジェクトを解放する、またはその逆)。