3

ネストされた配列を作成しようとしています。まず、ゲーム内の各プレーヤーのインベントリに対応するアイテムオブジェクトを含む10個の配列を含む「PlayerItems」配列を作成します。示された行で、次のエラーが発生します。

エラー:void値は無視されるべきであるため無視されません

ここでの無効値は何ですか?代わりに使用した場合[[PlayerItems objectAtIndex:i] addObject:myitem]、プログラムはコンパイルされますがクラッシュします。その行をコメントアウトすると、コンパイルされて正常に実行されます。ご協力ありがとうございました!

self.PlayerItems = [[NSMutableArray alloc] initWithCapacity:11];
NSMutableArray *itemarray = [[NSMutableArray alloc] initWithCapacity:60];
item *myitem = [[item alloc] init];
item.kind = 1;
for (int i = 1; i < 10; i++) {
    itemarray = [[NSMutableArray alloc] initWithCapacity:60];
    [PlayerItems addObject:itemarray];
    for (int i2 = 1; i2 < 50; i2++) {
        myitem = [[item alloc] init];
        myitem.kind = 1;
        // The error occurs on the line below:
        ((NSMutableArray *) [[PlayerItems objectAtIndex:i] addObject:myitem]);
    }
}
4

4 に答える 4

8

私は次のようにします:

self.playerItems = [[NSMutableArray alloc] initWithCapacity:11];

NSMutableArray * itemArray;
Item * anItem;
for (int playerIndex = 1; playerIndex <= 10; playerIndex++)
{
    itemArray = [NSMutableArray arrayWithCapacity:60];
    [playerItems addObject:itemArray];

    for (int itemIndex = 1; itemIndex <= 50; itemIndex++)
    {
        anItem = [[Item alloc] init];
        anItem.kind = 1;
        [itemArray addObject:anItem];
        [anItem release];
    }
}

補足として、元のコードにはメモリ リークがいっぱいあるため、Cocoa のメモリ管理について必ずお読みください。最初は頭を包み込むのは少し難しいかもしれませんが、一度それを学ぶと、それは第二の性質になります. 努力する価値は十分にあります。

アップデート:

これを行うためのよりオブジェクト指向の方法は、Playerクラスを作成し、それぞれPlayerに独自の項目セットを管理させることです。

Player.h

@interface Player : NSObject
{
    NSMutableArray * items;
}
@property (readonly) NSMutableArray * items;
@end

Player.m

#import "Player.h"
@implementation Player

@synthesize items;

- (id)init
{
    if ((self = [super init]) == nil) { return nil; }

    items = [[NSMutableArray alloc] initWithCapacity:60];
    Item * anItem;
    for (int itemIndex = 1; itemIndex <= 50; itemIndex++)
    {
        anItem = [[Item alloc] init];
        anItem.kind = 1;
        [items addObject:anItem];
        [anItem release];
    }

    return self;
}

- (void)dealloc
{
    [items release];
    [super dealloc];
}

@end

他の場所

NSMutableArray * allPlayers = [[NSMutableArray alloc] initWithCapacity:11];

Player * aPlayer;
for (int playerIndex = 1; playerIndex <= 10; playerIndex++)
{
    aPlayer = [[Player alloc] init];
    [allPlayers addObject:aPlayer];
    [aPlayer release];
}

...

[allPlayers release];
于 2009-08-07T14:16:11.823 に答える
5

こんにちは、ネストされた配列を構築しようとしています…</p>

そうしないでください。並列およびネストされた配列は、eJames が提案したような実際のオブジェクト指向ソリューション (モデル クラスの作成) よりも、読み書きが困難です。

すべてのプレーヤーの最初のアイテムのアイテムの種類を設定するコードを検討してください。並列/ネストされた配列の場合:

for (NSArray *items in PlayerItems)
    [[items objectAtIndex:0U] setKind:newKind];

モデル オブジェクトの場合:

for (Player *player in players)
    [player setKind:newKind];

どちらがより明確ですか?

並列配列とネストされた配列を維持し、変更ごとにそれらすべてを同期させ、それらの項目にアクセスするために必要な作業は、モデル クラスを作成するために必要な作業よりもはるかに多くなります。さらに、Mac に移植することに決めた場合、バインディングを使用できず、AppleScript サポートの実装 (ゲームにとってはそれほど大したことではないことは認めます) がほぼ不可能であるため、モデル クラスを持たないと積極的に損をします。

eJames も述べたように、オブジェクトを大量にリークしています。彼の推奨に従って、Cocoa のメモリ管理プログラミング ガイドを読んでください。

pgb が言ったように、Cocoa (および C も同様) の配列インデックスは 0 から始まります。配列を反復処理するより明確な方法については、上記のコード例を参照してください。

pgb と Christian の両方が指摘しているように、addObject:は を返すメソッドでvoidあり、それを にキャストしNSMutableArray *ます。おそらく、そのキャストを角括弧の最初のペアの中に入れるつもりでしたか? しかし、これは、実際のモデル クラスがあれば、アイテムを含む新しい Player に関するすべてを一度に設定することになるため、発生しない別の問題です。

Player *player = [[Player alloc] init];

//Set up name, SPECIAL stats, etc.

for (int kind = 1; kind < 50; ++kind) {
    Item *item = [[Item alloc] init]; //I capitalized your class name for you.
    [item setKind:kind];
    [player addInventoryObject:item]; //Assume “inventory” is the name of the property that holds the player's items.
    [item release];
}

[allPlayers addObject:player];
[player release];

これにより、もう 1 つの提案が得られます。項目の種類のモデル クラスを作成し、それらの配列をどこかに配置することもできます。次に、それぞれの種類に名前、アイコン、おそらく説明、片手対両手などの性質、クラス要件、ステータス要件などをすべて item-kind オブジェクトに含めることができます。ループは次のようになります。

for (ItemKind *kind in [self kindsOfItems]) {
    Item *item = [[Item alloc] initWithKind:kind];
    [player addInventoryObject:item];
    [item release];
}

さらに、このプロパティを拡張可能に設計するkindsOfItemsと、プラグイン (Mac) またはアプリ内購入 (iPhone) のいずれかを使用して、プレーヤーが後でより多くのアイテムの種類を追加できるようになります。

于 2009-08-07T14:56:33.507 に答える
1

Objective-C の配列は 0 ベースであり、for ループは 1 から始まります。これを次のように変更する必要があります。

for (int i = 0; i < 10; i++)

void エラーについては、void を返すため、戻り値をキャストする必要はありませんaddObject:。そのため、警告が表示されます。

その行は次のようになります。

[[PlayerItems objectAtIndex:i] addObject:myitem];
于 2009-08-07T14:09:07.217 に答える
1

最後の行でaddObject:を呼び出しています。これは void: を返します。

- (void)addObject:(id)anObject

次に、void を NSMutableArray* にキャストしようとします。また、キャストされたボイドを何にも割り当てません。

サブ配列を配列に追加するには、これで十分です。

[[PlayerItems objectAtIndex:i] addObject:myitem];

ところで: 9 つの配列のみを作成し、49 のサブ配列のみを追加しています。

于 2009-08-07T14:09:30.757 に答える