将对象存储到NSMutableArray

问题描述:

请纠正我,我错了(我是一个begginer) 我想存储一个类对象到NSArray中。例如:将对象存储到NSMutableArray

MySimpleClass *mscObj = [[MySimpleClass alloc] initWithSomething:@"something"]; 
NSMutableArray *myarr = [[NSMutableArray alloc] init]; 
[myarr addObject:mscObj]; 
mscObj = @"somethingelse"; 

然后我的myarr索引0从@“something”变成@“somethingelse”。为什么?我可以仅将副本存储到数组中吗?

编辑: 在MySimpleClass:

#import <Foundation/Foundation.h> 

@interface MySimpleClass : NSObject { 
} 

@property (strong,nonatomic) NSString *objectName; 
@property (strong,nonatomic) NSString *objectTarget; 

-(void)addName:(NSString*)name; 
-(void)addTarget:(NSString*)target; 


@end 

.m文件

#import "MySimpleClass.h" 

@implementation MySimpleClass 

@synthesize objectName; 
@synthesize objectTarget; 

-(void)addName:(NSString*)name{ 
    self.objectName = name; 
} 

-(void)addTarget:(NSString*)target{ 
    self.objectTarget = target; 
} 

-(void)flushAll { 
    self.objectTarget = nil; 
    self.objectName = nil; 
} 

@end 

在其它类的,我有:

MySimpleClass *mscObj = [[MySimpleClass alloc] initWithSomething:@"something"]; 


[myarr addObject:[mscObj copy]]; 

     int testunit = [myarr count]; 
     for(int i=0;i<testunit;i++) { 
      MySimpleClass *myelement = [myarr objectAtIndex:i]; 
      NSLog(@"%@ : %@",myelement.objectName,myelement.objectTarget); 
     } 
+0

你改变了mscObj和NSArray的值只存储对象的refence。你的myarr索引0指的是对象值已被改变的同一个对象。如果你想在0的索引应该有“东西”,并在1索引它应该是“somethingelse”,那么你必须保持索引0的对象的副本,然后通过使用addObject:方法添加更新的副本mscObj索引1 – dayitv89 2012-04-17 13:16:30

尝试:

[myarr addObject:[[mscObj copy] autorelease]]; 
+0

之后,我得到一个错误:[mscObj copyWithZone:]:无法识别的选择器发送到实例。我应该在课堂上写出方法副本吗?但我应该在那里放? – Kuba 2012-04-17 13:05:54

+0

无需编写任何方法,上面的代码应该工作得很好。你在哪里放置你的代码?你的对象是一个Core-Data对象吗? – sooper 2012-04-17 13:08:33

+0

我向我的问题添加了代码,谢谢。 – Kuba 2012-04-17 13:18:03

这是因为指针。索引号为0的对象保留在内存中的相同位置,它会一直改变。

尝试添加阵列后releagind的mscObj并创建一个新MySimpleClass物体@“somethingelse”

mscObj是参考什么数组商店引用。所以如果你从容器外部操作一个对象,那么参考反映了这些变化。通过参考差异考虑价值。

当你做到这一点

[myarr addObject:mscObj]; 

myArr,该被保留到mscObj参考。所以任何时候mscObj被改变myarr都会反映这个改变。

当你做到这一点

[myarr addObject:[mscObj copy]]; // I've left the autorelease out for simplicity 

myArr,该保留mscObj的新副本的引用。当mscObj被更新时,myarr将不会反映更改,因为它的参考点指向完全不同的对象。

编辑

对于复印工作类** ** MySimpleClass需要实现NSCopying。看到这个SO答案就可以了。

+0

正如我下面所说:在此之后,我收到一个错误:[mscObj copyWithZone:]:无法识别的选择器发送到实例。我应该在课堂上写出方法副本吗?但我应该在那里放? – Kuba 2012-04-17 13:08:30

+1

要使拷贝正常工作 - 您需要查看** NSCopying ** - 这是协议** MySimpleClass **需要实现的方法调用,例如** copy **才能工作。 – Damo 2012-04-17 13:17:34

+0

我现在加入这个,没有错误编译,但仍然没有我的数组中的实例的副本。所以问题依然存在。 – Kuba 2012-04-17 13:28:34

鉴于你已经发布的代码中,阵列中的第一个对象(索引0)将不会改变由于第四行中,mscObj = @"something else";。该行改变指针mscObj本身的价值,所以它会指向一个完全不同的对象。如果数组中的对象发生变化,我相信,你正在使用不完全匹配您发布什么真正的代码 - 请检查。

mscObj.something = @"somethingelse"; 

这里你改变:

但是,如果您使用mscObj指针更改它指向的对象的属性,那么你就必须在阵列中更改了对象mscObj指的对象的something属性,但是您不会更改mscObj的值。这更改数组中的对象的内容,因为这是mscObj指向相同的对象。

+0

是的,你说得对,对不起,我不认为这有什么不同。我将代码添加到我原来的问题中。谢谢。 – Kuba 2012-04-17 13:17:35