2012-04-17 100 views
0

請糾正我,我錯了(我是一個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

回答

1

嘗試:

[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

這是因爲指針。索引號爲0的對象保留在內存中的相同位置,它會一直改變。

嘗試添加陣列後releagind的mscObj並創建一個新MySimpleClass物體@「somethingelse」

0

mscObj是參考什麼數組商店引用。所以如果你從容器外部操作一個對象,那麼參考反映了這些變化。通過參考差異考慮價值。

1

當你做到這一點

[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

3

鑑於你已經發布的代碼中,陣列中的第一個對象(索引0)將不會改變由於第四行中,mscObj = @"something else";。該行改變指針mscObj本身的價值,所以它會指向一個完全不同的對象。如果數組中的對象發生變化,我相信,你正在使用不完全匹配您發佈什麼真正的代碼 - 請檢查。

mscObj.something = @"somethingelse"; 

這裏你改變:

但是,如果您使用mscObj指針更改它指向的對象的屬性,那麼你就必須在陣列中更改了對象mscObj指的對象的something屬性,但是您不會更改mscObj的值。這更改數組中的對象的內容,因爲這是mscObj指向相同的對象。

+0

是的,你說得對,對不起,我不認爲這有什麼不同。我將代碼添加到我原來的問題中。謝謝。 – Kuba 2012-04-17 13:17:35