web-dev-qa-db-ja.com

Objective Cで整数プロパティの配列を作成する

私はObjective Cで整数の配列のプロパティを作成するのに苦労しています正しく、または代替ソリューションを提供します。

myclass.h

@interface myClass : NSObject {

@private int doubleDigits[10];
}

@property int doubleDigits;
@end

myclass.m

@implementation myClass

    @synthesize doubleDigits;
    -(id) init {

        self = [super init];

        int doubleDigits[10] = {1,2,3,4,5,6,7,8,9,10};

        return self;
    }

    @end

ビルドして実行すると、次のエラーが表示されます。

エラー:プロパティ 'doubleDigits'のタイプがivar 'doubleDigits'のタイプと一致しません

誰かが解決策を提供するか、私を正しい方向に導くことができることを願っています。

前もって感謝します。

58
woopstash

これは動作するはずです:

@interface MyClass
{
    int _doubleDigits[10]; 
}

@property(readonly) int *doubleDigits;

@end

@implementation MyClass

- (int *)doubleDigits
{
    return _doubleDigits;
}

@end
30
robottobor

C配列は、プロパティでサポートされているデータ型の1つではありません。宣言されたプロパティページのXcodeドキュメントの「Objective-Cプログラミング言語」を参照してください。

サポートされているタイプ

任意のObjective-Cクラス、Core Foundationデータ型、または「Plain Old Data」(POD)型のプロパティを宣言できます(C++ Language Note:POD Typesを参照)。ただし、Core Foundationタイプの使用に関する制約については、「Core Foundation」を参照してください。

PODにはC配列は含まれません。 http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html を参照してください

配列が必要な場合は、NSArrayまたはNSDataを使用する必要があります。

回避策は、私が見るように、(void *)を使用して型チェックを回避するようなものです。それはできますが、コードの保守性が低下します。

20
lucius

ルシウスが言ったように、C配列プロパティを持つことはできません。 NSArrayを使用する方法があります。配列はオブジェクトのみを保存するため、NSNumbersを使用してintを保存する必要があります。新しいリテラル構文を使用すると、初期化は非常に簡単で簡単です。

NSArray *doubleDigits = @[ @1, @2, @3, @4, @5, @6, @7, @8, @9, @10 ];

または:

NSMutableArray *doubleDigits = [NSMutableArray array];

for (int n = 1; n <= 10; n++)
    [doubleDigits addObject:@(n)];

詳細: NSArrayクラスリファレンスNSNumberクラスリファレンスリテラル構文

16
Tim Vermeulen

私は推測しています:

Ivarsで定義された変数は、オブジェクト内にスペースを割り当てると思います。これにより、関数に値で配列を渡すことはできず、ポインタを介してのみアクセスできるため、アクセサを作成できなくなります。したがって、ivarsでポインターを使用する必要があります。

int *doubleDigits;

そして、initメソッドでそのためのスペースを割り当てます:

@synthesize doubleDigits;

- (id)init {
    if (self = [super init]) {
        doubleDigits = malloc(sizeof(int) * 10);
        /*
         * This works, but is dangerous (forbidden) because bufferDoubleDigits
         * gets deleted at the end of -(id)init because it's on the stack:
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * [self setDoubleDigits:bufferDoubleDigits];
         *
         * If you want to be on the safe side use memcpy() (needs #include <string.h>)
         * doubleDigits = malloc(sizeof(int) * 10);
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * memcpy(doubleDigits, bufferDoubleDigits, sizeof(int) * 10);
         */
    }
    return self;
}

- (void)dealloc {
    free(doubleDigits);
    [super dealloc];
}

この場合、インターフェースは次のようになります。

@interface MyClass : NSObject {
    int *doubleDigits;
}
@property int *doubleDigits;

編集:

これが許可されているかどうか、私は本当に確信していません。これらの値は本当にスタック上にあるのでしょうか、それとも別の場所に格納されているのでしょうか?これらはおそらくスタックに格納されているため、このコンテキストで使用するのは安全ではありません。 ( 初期化子リストに関する質問 を参照)

int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
[self setDoubleDigits:bufferDoubleDigits];
12
Georg Schölly

これは動作します

@interface RGBComponents : NSObject {

    float components[8];

}

@property(readonly) float * components;

- (float *) components {
    return components;
}
6
Martin West

これをクラスの.hファイルに入れて、XCode 7でプロパティとして定義できます。

@property int  (*stuffILike) [10];
1

以前の回答はすべて複雑すぎると感じました。プロパティとしていくつかのintの配列を保存する必要があり、NSArrayを使用するというObjC要件が私のソフトウェアの不必要な複雑さであることがわかりました。

だから私はこれを使用しました:

typedef struct my10ints {
    int arr[10];
} my10ints;

@interface myClasss : NSObject

@property my10ints doubleDigits;

@end

これは、Xcode 6.2を使用して正常にコンパイルされます。

私の意図)はこのように使用することでした:

myClass obj;
obj.doubleDigits.arr[0] = 4;

ただし、これは機能しません。これが生成するものです。

int i = 4;
myClass obj;
obj.doubleDigits.arr[0] = i;
i = obj.doubleDigits.arr[0];
// i is now 0 !!!

これを正しく使用する唯一の方法は次のとおりです。

int i = 4;
myClass obj;
my10ints ints;
ints = obj.doubleDigits;
ints.arr[0] = i;
obj.doubleDigits = ints;
i = obj.doubleDigits.arr[0];
// i is now 4

そして、私のポイントを完全に無効にします(NSArrayを使用する複雑さを回避します)。

0
gog