0

Please, correct me, where i'm wrong (i'm a begginer) I want to store a class objects into NSArray. For example:

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

And then my myarr index 0 change from @"something" to @"somethingelse". Why? Can i store a copy only to array?

EDIT: In 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 file

#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

Then In other class i have:

   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);
        }
Jakub
  • 13,712
  • 17
  • 82
  • 139
  • u changed the value of mscObj and NSArray store only refence of object. ur myarr index 0 refer to same object where object value has been changed. if u want that ur index at 0 should have "something" and at index at 1 it should be "somethingelse" then u have to keep copy of object at index 0 and then add updated copy of mscObj to index 1 by using addObject: method – gauravds Apr 17 '12 at 13:16

5 Answers5

3

Given the code you've posted, the first object (index 0) in the array won't change due to the fourth line, mscObj = @"something else";. That line changes the value of the pointer mscObj itself, so that it'll point to a completely different object. If the object in the array is changing, I believe that the real code you're using won't quite match what you've posted -- please check that.

However, if you use the mscObj pointer to change an attribute of the object that it points to, then you'll have changed the object in the array:

mscObj.something = @"somethingelse";

Here you're changing the something property of the object that mscObj refers to, but you're not changing the value of mscObj. This will change the contents of the object in the array, since that's the same object that mscObj points to.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Yes, you're right, Sorry, i don't think this is something different. I add code to my original question. Thanks. – Jakub Apr 17 '12 at 13:17
1

Try:

[myarr addObject:[[mscObj copy] autorelease]];
sooper
  • 5,991
  • 6
  • 40
  • 65
  • After this I'm getting an error: [mscObj copyWithZone:]: unrecognized selector sent to instance. Should I write method copy in my class? But what should i put there? – Jakub Apr 17 '12 at 13:05
  • No need to write any methods, the above code should work just fine. Where are you placing your code? Is your object a Core-Data object? – sooper Apr 17 '12 at 13:08
  • What is `listElements`? It doesn't show up anywhere in your code. – sooper Apr 17 '12 at 13:22
  • Sorry, i've tried different class, and copy old version. Post updated. – Jakub Apr 17 '12 at 13:24
  • I'm right now fix error by add @protocol to class, but still don't have a copy in index 0. Still is the last motified version on my class instance. – Jakub Apr 17 '12 at 13:30
  • OK, i'm write a empty method copy in mysimpleclass, and it works! Thanks! – Jakub Apr 17 '12 at 13:41
1

When you do this

[myarr addObject:mscObj];

myarr is retaining a reference to mscObj. So any time mscObj is changed myarr will reflect that change.

When you do this

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

myarr retains a reference to a new copy of mscObj. When mscObj is then updated myarr will not reflect the change because it's reference points to a completely different object.

EDIT

For copy to work your class ** MySimpleClass** needs to implement NSCopying. See this SO answer for help on that.

Community
  • 1
  • 1
Damo
  • 12,840
  • 3
  • 51
  • 62
  • As i said below: After this I'm getting an error: [mscObj copyWithZone:]: unrecognized selector sent to instance. Should I write method copy in my class? But what should i put there? – Jakub Apr 17 '12 at 13:08
  • 1
    For copy to work correctly - you need to look up **NSCopying** - which is the protocol ** MySimpleClass** needs to implement for method calls such as **copy** to work. – Damo Apr 17 '12 at 13:17
  • I add this, now, compile without error, but still i don't have a copy of instance in my array. So problem still exist. – Jakub Apr 17 '12 at 13:28
0

It is because of the pointers. Your object at index:0 remains at the same location in the memory.It will always change.

try releagind the mscObj after adding the array and create a new MySimpleClass object with @"somethingelse"

mhunturk
  • 296
  • 2
  • 12
0

mscObj is a reference and what the array stores are references. So if you manipulate a object from outside the container the reference reflects the changes. Think about the by value by reference difference.

hburde
  • 1,441
  • 11
  • 6