0

I'm building an app whereas I have a ViewController viewing a custom object, lets call this object "CustomObject". Upon a button press, a segue is triggered and hence prepareForSegue is called where I get the destination ViewController and pass self.myObject. The destination ViewController may change a few parts of the CustomObject, but those changes should not be reflected in the original ViewController if the user decides to go back to the original ViewController. The changes should only be reflected if the user pressed "Save" in the destination ViewController and hence triggering an NSNotification with a version of the CustomObject that should be reloaded in the original ViewController like so:

self.myObject = (CustomObject *)notification.object;

So my question is as follows: Which of these should I use (or any other that would be correct) - and why?

@property (nonatomic, strong) CustomObject *myObject;
@property (nonatomic, copy) CustomObject *myObject;

Thanks!

Update:

header file:

@interface CustomObject : NSObject <NSCopying>

implementation file:

- (id)copyWithZone:(NSZone *)zone
{
id copy = [[[self class] alloc] init];
if (copy)
{
    // Copy NSObject subclasses
    [copy setRegisterDate:[self.registerDate copyWithZone:zone]];

}
return copy;
}
Erik
  • 2,500
  • 6
  • 28
  • 49
  • Sounds like you are re-inventing a lot of the change management functionality in Core Data, btw. Even if the re-invention is warranted (which it might likely be), you can likely learn a lot by the way Core Data works. – bbum Apr 17 '15 at 20:22

3 Answers3

2

You should use strong but (in prepareForSegue) create and pass a copy (or simply a different object, but in any case, don't pass the original object).

This is the opposite of the situation for which the copy property attribute was designed. With the copy property attribute, the recipient wants to ensure that the object is not mutated later behind his back: e.g., I accept an NSString but the caller passes me an NSMutableString and retains it as well, so that my string can now be changed behind my back. By calling copy, I turn the NSMutableString into an NSString, which is immutable.

Your situation, as I said, is just the opposite. Your first view controller wants to pass an object without any risk of affecting his own object. Therefore, it is up to your first view controller to make a new object and pass it, rather than passing a pointer to his own sacred object. It is not your second view controller's job to know that your first view controller needs protecting; it is up to your first view controller to protect himself.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Would the best way of creating a new but equal object (property-wise) be to make a function with CustomObject as return type and a CustomObject as argument, then just manually copy over all the properties to a new CustomObject instance? – Erik Apr 17 '15 at 17:53
  • Basically you are describing an implementation of `copyWithZone:`. So you may as well fix up your CustomObject to adopt NSCopying and implement `copyWithZone:`. You would have had to do that no matter which solution you chose! – matt Apr 17 '15 at 17:54
  • Or you could write an initializer `initWithOtherCustomObject:` that copies the other custom object's properties. But it amounts to the same thing, obviously. – matt Apr 17 '15 at 18:00
  • that last solution appears to very solid. Very little code and I won't have to write the copying code on every ViewController that'll benefit from it – Erik Apr 17 '15 at 18:11
  • But the same thing is true for `copyWithZone:`, since now anyone can call `copy` on a CustomObject. All you are saying is that knowledge of how to duplicate oneself should belong to _oneself_, which is obvious. (But perhaps it is not obvious to _you_, since your whole question is about who should know what. That is the art of object-oriented programming!) – matt Apr 17 '15 at 18:13
  • I will look into CopyWithZone and have that implemented and continue my learning journey for best possible programming !;) – Erik Apr 17 '15 at 18:21
  • please take a look at my update, is that the correct way of using copyWithZone: ? – Erik Apr 17 '15 at 21:14
  • @Erik You should study Apple's documentation on how to write `copyWithZone:` implementations. – matt Apr 17 '15 at 21:24
0

You should use "copy", because "copy" creates a duplicate instance of that object, and the new object is independent of the original object. "strong" adds a "link" to the object, it's only one object.

Cristik
  • 30,989
  • 25
  • 91
  • 127
Flolangka
  • 1
  • 1
0

I feel you can go for copy. Since it can be used when the object is mutable. Use this if you need the value of the object as it is at this moment. You don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.

Pl. refer to the below link also which gives good insight when to use which property. Objective-C declared @property attributes (nonatomic, copy, strong, weak)

Community
  • 1
  • 1
shri
  • 856
  • 1
  • 10
  • 26