1

NSStrings へのポインターの動的な 2 次元 C 配列を含むクラスを作成したいと考えています。複数の NSArray を含む NSArray を使用して 2 次元配列をシミュレートできることはわかっていますが、可能であれば、従来の 2 次元 c-array を使用してこれを実行したいと考えています。ARC は、「__unsafe_unretained」を使用しない限り、NSString へのポインターを c-array の要素に単純に割り当てることを許可しません。

@interface NumberStringsArray : NSObject
{
  @public
  NSString * __unsafe_unretained **_array;
}

メモリ リークを回避し、c-array に割り当てられた各 NSString のクラス所有権をオブジェクトに与えるために、各 NSString オブジェクトへのポインターを NSMutableArray に追加します。-(void)dealloc では、取得したメモリを解放して、2 次元の c-array を作成します。

これが私の質問です: _array ivar に基づいてプロパティを宣言し、配列の i,j 要素を "foobar->array[i" ではなく "foobar.array[i][j]" として参照するにはどうすればよいですか? ][j]"?

後の増幅: __bridgeのものを除いて、回答者と非常によく似た方法でそれを行いました。それが違いを生むかどうかはわかりません。ここで 2 次元配列を割り当てます。

self->_array = (NSString * __unsafe_unretained **)calloc(_columnCount, sizeof(void *));
if (!self->_array)
  return nil;
for (UINT16 i = 0; i < _columnCount; i++)
{
  self->_array[i] = (NSString * __unsafe_unretained *)calloc(_rowCount, sizeof(void *));
  if (!self->_array[i])
  {
    for (UINT16 a = 0; a < _columnCount; a++)
      if (self->_array[a])
        free(self->_array[a]);
    if (self->_array)
      free(self->_array);
    return nil;
  }
}

コンマ区切り値のファイルから生成された部分文字列を使用して、NSString オブジェクトへのポインターを配列に入れます。

NSArray *numbers = [line componentsSeparatedByString: @","];
for (UINT16 i = 0; i < _columnCount; i++)
{
  NSString *number = @"";
  if (i < [numbers count])
    number = [numbers objectAtIndex: i];
  //
  // save it in owners
  //
  [self.owners addObject: number];
  self->_array[i][j] = number;
}

-(void)dealloc で、すべてのメモリを解放します。

-(void)dealloc
{
  for (UINT16 i = 0; i < self.columnCount; i++)
    if (self->_array[i])
      free(self->_array[i]);
  if (self->_array)
    free(self->_array);
}
4

3 に答える 3

0

このプロパティを宣言します。

@property (nonatomic) NSString * __unsafe_unretained **_array;

次に、ポインタをオブジェクトに割り当てることができます。

_array= (NSString * __unsafe_unretained **) malloc(M*sizeof(CFTypeRef) );
for(NSUInteger i=0; i<M;i++)
{
    _array[i]= ((NSString * __unsafe_unretained *) malloc(N*sizeof(CFTypeRef) );
    for(NSUInteger j=0; j<N;j++)
    {
        _array[i][j]= (__bridge NSString*) (__bridge_retained CFTypeRef) [[NSString alloc]initWithCString: "Hello" encoding: NSASCIIStringEncoding];
        // I see that you got habit with C so you'll probably like this method
    }
}

次に、それが不要になったら、アレイを解放します。

for(NSUInteger i=0; i<M; i++)
{
    for(NSUInteger j=0; j<N;j++)
    {
        CFTypeRef string=(__bridge_transfer CFTypeRef) _array[i][j];
    }
    free(_array[i]);
}
free(_array);
于 2012-12-07T19:32:32.673 に答える
0

(注: これは、データにアクセスするためのプロパティの作成/使用に対処するものであり、従来の Objective-C ストレージ管理または ARC によってデータを管理する方法ではありません。それについて考えると頭が痛くなります。)

読み取り専用の C 配列を Objective-C プロパティのように「見える」ようにする場合は、 などのプロパティを宣言して@property (readonly, nonatomic) char* myProp;から、 を使用するのではなく、@synthesize次の行に沿って getter を実装します。

-(char**)myProp {
    return myPropPointer;
    // Or, if the array is allocated as a part of the instance --
    return &myPropArray[0];
}
于 2012-12-07T19:54:53.040 に答える
0

Objective-C クラスの具体的なオブジェクトを宣言できないため、できません。そう

NumberStringsArray object;

許可されていません

あなたはそれを次のように宣言することを余儀なくされています

NumberStringsArray *object = [[NumberStringsArray alloc] init.. ];

->そのため、ポインターに適用された正しい演算子を介して ivar にアクセスする必要があります。Objective-C のは、標準の C では、具体的なフィールドへのアクセスに使用するものobject.somethingの省略形にすぎないことに注意してください。[object something].struct

于 2012-12-06T00:41:48.087 に答える