Objective-C中的嵌套数组(NSMutableArray)

use*_*526 3 arrays cocoa nested objective-c nsmutablearray

我正在尝试构建一个嵌套数组:首先,我创建一个"PlayerItems"数组,其中包含10个数组,每个数组包含项目对象,对应于游戏中每个玩家的库存.在指示的行上,我收到以下错误:

错误: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]);
    }
}
Run Code Online (Sandbox Code Playgroud)

e.J*_*mes 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];
    }
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,您应该阅读Cocoa中的内存管理,因为您的原始代码充满了内存泄漏.一开始可能有点困难,但一旦你学会了它,它就成了第二天性.非常值得的努力.

更新:

更加面向对象的方法是创建一个Player类,并让每个类Player管理自己的一组项:

Player.h

@interface Player : NSObject
{
    NSMutableArray * items;
}
@property (readonly) NSMutableArray * items;
@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

别处

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];
Run Code Online (Sandbox Code Playgroud)


Pet*_*sey 5

嗨,我正在尝试构建一个嵌套数组......

不要那样做.并行和嵌套数组比真正面向对象的解决方案更难编写和读取,如eJames建议的那样,即创建模型类.

考虑用于设置每个玩家的第一个项目的项目类型的代码.使用并行/嵌套数组:

for (NSArray *items in PlayerItems)
    [[items objectAtIndex:0U] setKind:newKind];
Run Code Online (Sandbox Code Playgroud)

使用模型对象:

for (Player *player in players)
    [player setKind:newKind];
Run Code Online (Sandbox Code Playgroud)

哪一个更清楚?

维护并行和嵌套数组所需的工作,以使每个更改保持同步并访问其中的任何项目,远远大于创建模型类所需的工作.此外,如果你决定移植到Mac,没有一个模型类会主动伤害你,因为你不能使用Bindings并实现AppleScript支持(对于游戏而言,这不是一件大事,我承认)几乎是不可能的.

正如eJames也提到的那样,你正在大量泄漏物品.按照他的建议阅读Cocoa的内存管理编程指南.

正如pgb所说,Cocoa(和C)中的数组索引从0开始.此外,除非必须,否则通常不使用索引; 请参阅上面的代码示例,以便更加清晰地迭代数组.

正如pgb和Christian都指出的那样,addObject:是返回的方法,void然后你将其转换为NSMutableArray *.也许你的意思是把那个演员放在第一对方括号内?但是如果你有一个真正的模型类,这是你不会遇到的另一个问题,因为你会立即设置关于新玩家的所有内容,包括他的项目:

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];
Run Code Online (Sandbox Code Playgroud)

这给我带来了另外一个建议:您可能还想为项类型创建一个模型类,并在某个地方有一个数组.然后,每种类型都可以有一个名称,一个图标,也许是一个描述,诸如单手与双手的性质,类要求,统计要求等等,都在项目类对象中.然后循环看起来像这样:

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

此外,如果您kindsOfItems可以扩展地设计此属性,则可以允许玩家稍后通过插件(Mac)或应用内购买(iPhone)添加更多项目种类.