1

I want to make sure I understand a key concept of properties and instance variable ownership of a class, in this case using NSArray.

Suppose I pass a reference to an NSArray to another class, and set that class's iVar to it. For example:

First Technique

OtherClass.h

@property (nonatomic, retain) NSArray * otherClassArray;

then:

CurrentClass.m

otherclass.otherClassArray=myArray

Now, even though OtherClass is retaining myArray, if CurrentClass changes myArray then otherclass.otherClassArray will also change, correct?

So, is this the better way to do it, or am I mistaken and the above will do what I'd expect from the following anyway:

Second Technique

CurrentClass.m

otherclass.otherClassArray=[NSArray arrayWithArray:myArray]

Now there is a distinct copy being made so any changes to myArray have no effect on otherClassArray, am I right, or are both of these approaches doing the same thing?

UPDATE: Is there any reason why my second technique above should or should not be used vs. using copy with the property? It would seem that either technique results in a new NSArray that my class owns.

johnbakers
  • 24,158
  • 24
  • 130
  • 258

1 Answers1

1

This is exactly why it is generally recommended that properties whose classes have mutable subclasses (most notably, NSString and the various collection classes) be declared as copy:

@property (nonatomic, copy) NSArray * otherClassArray;

Then whenever you set the property, OtherClass will get its own version of the array.

Your second technique has the same result as declaring a copy property, yes, but it should be left up to the property's owner whether it wants a copy or not. To put it another way, the principle of encapsulation demands that client code (CurrentClass) not be responsible for knowing that OtherClass needs to have its own version of the object. It's a matter of design and maintainability.

Community
  • 1
  • 1
jscs
  • 63,694
  • 13
  • 151
  • 195
  • I was using NSArray as an example, but suppose it was any kind of class, the question is the same; in my example, my class doesn't have its own copy of the object data unless it creates a new one, right? – johnbakers Mar 30 '12 at 06:09
  • put another way, by not using `copy` in the property, my second example would still give distinct object data to OtherClass, right? – johnbakers Mar 30 '12 at 06:11
  • Yes and yes; the key factor in deciding whether to use `copy` is, as I said, whether the class of the property has a mutable subclass. – jscs Mar 30 '12 at 07:07