使用自定义对象创建NSMutableArray的副本

时间:2022-09-24 22:51:27

I've been searching around for the solution to this for quite a while, and none of the other threads have helped. Basically, what I want to accomplish is creating an array of custom objects as a singleton, load them into my level, then create a copy of them since variables assigned to these objects will be manipulated. When the level is complete (or failed) though, I want these objects to remain the same so I can reload them.

我一直在寻找解决方案很长一段时间,其他线程都没有帮助。基本上,我想要完成的是创建一个自定义对象数组作为单例,将它们加载到我的级别,然后创建它们的副本,因为将操纵分配给这些对象的变量。但是当级别完成(或失败)时,我希望这些对象保持不变,以便我可以重新加载它们。

Below are some things I've tried.

以下是我尝试过的一些事情。

- (void)spawnStartTiles {
    //where _puzzleGridTilesArray and curLevel.gridTiles are NSMutableArrays
    [_puzzleGridTilesArray removeAllObjects];
    _puzzleGridTilesArray = [curLevel.gridTiles mutableCopy];
    CCLOG(@"tile in curlevel %@", curLevel.gridTiles[0]); //want these to log DIFFERENT objects
    CCLOG(@"tile in puzzle array %@", _puzzleGridTilesArray[0]);//want these to log DIFFERENT objects
}

The above logs the same object ID.

以上记录了相同的对象ID。

- (void)spawnStartTiles {
    //where _puzzleGridTilesArray and curLevel.gridTiles are NSMutableArrays
    _puzzleGridTilesArray = [self cloneArray:curLevel.gridTiles];
    CCLOG(@"tile in curlevel %@", curLevel.gridTiles[0]); //want these to log DIFFERENT objects
    CCLOG(@"tile in puzzle array %@", _puzzleGridTilesArray[0]);//want these to log DIFFERENT objects
}

-(NSMutableArray*)cloneArray:(NSMutableArray *)myArray {
    return [[NSMutableArray alloc] initWithArray: myArray];
}

Still logs same object ID.

仍记录相同的对象ID。

- (void)spawnStartTiles {
    //where _puzzleGridTilesArray and curLevel.gridTiles are NSMutableArrays
    _puzzleGridTilesArray = [[NSMutableArray alloc] initWithArray:curLevel.gridTiles copyItems:YES];
    CCLOG(@"tile in curlevel %@", curLevel.gridTiles[0]); //want these to log DIFFERENT objects
    CCLOG(@"tile in puzzle array %@", _puzzleGridTilesArray[0]);//want these to log DIFFERENT objects
}

The above gives a runtime error. I think this is because the objects I am copying are a custom class named Tile. The class is a CCNode, and the .h file is below.

以上给出了运行时错误。我想这是因为我复制的对象是一个名为Tile的自定义类。该类是CCNode,.h文件位于下方。

#import "CCNode.h"

@interface Tile : CCNode

@property (nonatomic, assign) NSInteger value;
@property (nonatomic, assign) NSInteger gemLevel;
@property (nonatomic, assign) BOOL mergedThisRound;
- (void)updateValueDisplay:(BOOL)bannerTiles difficultyMode:(int)difficultyMode;
- (void)updateOpacity:(NSInteger)opacityVariable;
- (void)tileHasBeenSelected:(BOOL)tileHasBeenTouched;

@end

Is there a way to somehow transform this class so that is can be copied? I've looked at http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C and Implementing NSCopying and I'm still confused, so further help would be greatly appreciated. Thank you!

有没有办法以某种方式转换这个类,以便可以复制?我查看了http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C和实施NSCopying,我仍然感到困惑,所以非常感谢您的进一步帮助。谢谢!

1 个解决方案

#1


6  

You get an error because [[NSMutableArray alloc] initWithArray:curLevel.gridTiles copyItems:YES] calls copyWithZone: on each item in the array. Your items must conform to NSCopying for you to use this method, but this is the correct approach.

您收到错误,因为[[NSMutableArray alloc] initWithArray:curLevel.gridTiles copyItems:YES]对数组中的每个项目调用copyWithZone:您的项目必须符合NSCopying才能使用此方法,但这是正确的方法。

To implement NSCopying:

实施NSCopying:

  1. Update your Tile class to add the protocol, i.e. @interface Tile : CCNode <NSCopying>
  2. 更新您的Tile类以添加协议,即@interface Tile:CCNode

  3. Implement the method - (id)copyWithZone:(NSZone *)zone in your Tile implementation.
  4. 在Tile实现中实现方法 - (id)copyWithZone:(NSZone *)区域。

  5. In that method, allocate a new instance of Tile and assign all of it's properties to that of your current instance.
  6. 在该方法中,分配一个新的Tile实例,并将其所有属性分配给当前实例的属性。

#1


6  

You get an error because [[NSMutableArray alloc] initWithArray:curLevel.gridTiles copyItems:YES] calls copyWithZone: on each item in the array. Your items must conform to NSCopying for you to use this method, but this is the correct approach.

您收到错误,因为[[NSMutableArray alloc] initWithArray:curLevel.gridTiles copyItems:YES]对数组中的每个项目调用copyWithZone:您的项目必须符合NSCopying才能使用此方法,但这是正确的方法。

To implement NSCopying:

实施NSCopying:

  1. Update your Tile class to add the protocol, i.e. @interface Tile : CCNode <NSCopying>
  2. 更新您的Tile类以添加协议,即@interface Tile:CCNode

  3. Implement the method - (id)copyWithZone:(NSZone *)zone in your Tile implementation.
  4. 在Tile实现中实现方法 - (id)copyWithZone:(NSZone *)区域。

  5. In that method, allocate a new instance of Tile and assign all of it's properties to that of your current instance.
  6. 在该方法中,分配一个新的Tile实例,并将其所有属性分配给当前实例的属性。