从 NSMutableArray 检索的数据与我保存到其中的数据不同

Data retrieved from a NSMutableArray are different with the one I saved into it

为什么从 NSMutableArray 中检索到的单元格的值与我最初存储在其中的单元格的值不同?

我有一个 属性 类型的 NSMutableArray,我用它来保存一个整数矩阵,代码如下

tiles = [[NSMutableArray alloc] initWithObjects:
         @1, @1, @1, @1, @1, @1,
         @1, @0, @0, @0, @0, @1,
         @1 ,@0, @0, @0, @0, @1,
         @1 ,@0, @0, @0, @0, @1,
         @1 ,@0, @0, @0, @0, @1,
         @1, @1, @1, @1, @1, @1,nil];


tileManager = [[TileManager alloc] init]; 
[tileManager CreateTilesMapRow:tilesMatrixWidth withColumns:tilesMatrixHeight byFlatDataArray:tiles];

这里是检索部分,它总是从 NSMutableArray 中 return@1,它是一个 "iso_wall"

-(void) placeAllTilesIso
{
    NSString *imageName;
    printf("Width , Height : %li , %li \n",(long)tilesMatrixWidth (long)tilesMatrixHeight);
    for (NSInteger i = 0;i<tilesMatrixWidth;i++)
   {
        for(NSInteger j = 0;j<tilesMatrixHeight;j++)
        {
            imageName = [tileManager getSpriteNameForRow:i andCol:j];
//HERE IS THE WRONG RESULT! Always says iso_wall! but It shouldn't if you take a look at tiles which includes both @0 and @1, where did the @0 went?
            NSLog(@"Sprite Got!  image name : %@ \n",imageName);
        }
    }
}

我还定义了 class 和 header,名称为 TileManager.m 和 TileManager.h,我计划在将来扩展它们,这是它们的代码:

这是TileManager.h

#import <UIKit/UIKit.h>
#import <math.h>
@interface TileManager : NSObject
@property (strong,nonatomic) NSMutableArray *tilesMatrix;
- (void) CreateTilesMapRow:(NSInteger) row withColumns:(NSInteger) col byFlatDataArray:(NSMutableArray*) flatArray;
- (NSString *) getSpriteNameForRow:(NSInteger) row andCol:(NSInteger) col;
@end

这是TileManager.m

#import "tileManager.h"
@implementation TileManager

//NSMutableArray *tilesMatrix;

- (void) CreateTilesMapRow:(NSInteger) row withColumns:(NSInteger) col byFlatDataArray:(NSMutableArray *) flatArray
    {

    _tilesMatrix = [[NSMutableArray alloc] initWithCapacity:row];
    NSMutableArray *innerTmp = [[NSMutableArray alloc] initWithCapacity:col];
    for (int i = 0;i < col;i++) [innerTmp addObject:@0];
    for (int i = 0;i < row;i++) [_tilesMatrix addObject:innerTmp];

   for (NSInteger rowIndex=0; rowIndex < row;rowIndex++)   
     {
        for (NSInteger colIndex=0; colIndex < col; colIndex++)
        {
            _tilesMatrix[rowIndex][colIndex] =(NSString*) flatArray[rowIndex*col+colIndex];
        //READ ME
        // This show everything is ok and the _tileMatrix contains both 0 and 1
            NSLog(@"Create : row : %li    col : %li  val : %@",(long)rowIndex,(long)colIndex,_tilesMatrix[rowIndex][colIndex]);
            }
        }
    }
}
-(NSString *) getSpriteNameForRow:(NSInteger) row andCol:(NSInteger) col 
{
    //README
    // This always writes 1 which is incorrect
    NSLog(@"GET : row : %li    col : %li  val : %@",(long)row,(long)col,_tilesMatrix[row][col]);
    if ([_tilesMatrix[row][col] isEqual:@1])
        return (NSString *) @"iso_wall";
    else
        return (NSString *) @"iso_ground";
}

为什么在 Objective C 中使用数组如此困难 !!!

for (int i = 0;i < col;i++) [innerTmp addObject:@0];

col 个零填充 innerTmp...

for (int i = 0;i < row;i++) [_tilesMatrix addObject:innerTmp];

innerTmp row 次添加到 _tilesMatrix...

您构建了一个矩阵,其中每一行都是对 相同 对象的引用 - innerTmp.

也许试试:

[_tilesMatrix addObject:[innerTmp mutableCopy]];

所以每一行都是不同的。

HTH

是否可能是这两行导致了问题:

for (int i = 0;i < col;i++) [innerTmp addObject:@0];
for (int i = 0;i < row;i++) [_tilesMatrix addObject:innerTmp];

不幸的是,我现在无法 运行 代码,但除了这些之外,其他一切看起来都很可靠。相同的 innerTmp 被添加到所有行。一样的记忆。相反也许:

for (int i = 0;i < row;i++) {
    NSMutableArray * innerTmp = [[NSMutableArray alloc] initWithCapacity:col];
    for (int j = 0;j < col;j++) {
        [innerTmp addObject:@0];
    }
    [_tilesMatrix addObject:innerTmp];
}