how do I set the value of an NSNumber variable (without creating a new object) in objective-c
Asked Answered
L

1

17

how do I set the value of an NSNumber variable (without creating a new object) in objective-c?

Background

  • I'm using Core Data and have a managed object that has an NSNumber (dynamic property)
  • passing (by reference) this to another method which will update it
  • not sure how to update it? if I allocate it another new NSNumber things don't work, which I guess makes sense it's then got a pointer to a different object not the core data object (I guess)
Loughlin answered 11/5, 2011 at 21:21 Comment(0)
B
16

An NSNumber object isn't mutable. This means that the only way to change a property containing a NSNumber is to give it a new NSNumber. To do what you want, you have three options:

1. Pass the Core Data object to the method and have it directly set the property.

- (void)updateNumberOf:(MyCoreDataObject *)theObject {
    NSNumber *newNumber = ...; // create new number
    theObject.number = newNumber;
}

Called as [self updateNumberOf:theCoreDataObject];

2. Have the update method return a new NSNumber and update it in the caller.

- (NSNumber *)updateNumber:(NSNumber *)oldNumber {
    NSNumber *newNumber = ...; // create new number
    return newNumber;
}

Called using:

NSNumber *theNumber = theCoreDataObject.number;
theNumber = [self updateNumber:theNumber];
theCoreDataObject.number = theNumber;

3. Pass a pointer to a number variable and update it in the caller (I would only suggest this over option 2 if you need to return something else).

- (void)updateNumber:(NSNumber **)numberPointer {
    if(!numberPointer) return; // or possibly throw an error
    NSNumber *oldNumber = *numberPointer;
    NSNumber *newNumber = ...; // create new number
    *numberPointer = newNumber;
}

Called using:

NSNumber *theNumber = theCoreDataObject.number;
[self updateNumber:&theNumber];
theCoreDataObject.number = theNumber;

I did not bother with memory management in any of these examples. Make sure you release/autorelease objects appropriately.

4. (from Greg's comment) Similar to option 1, but passes the key to the update method to be more portable.

- (void)updateNumberOf:(id)theObject forKey:(NSString *)key {
    NSNumber *oldNumber = [theObject valueForKey:key];
    NSNumber *newNumber = ...; // create new number
    [theObject setValue:newNumber forKey:key];
}

Called as [self updateNumberOf:theCoreDataObject forKey:@"number"];

Beauteous answered 11/5, 2011 at 21:33 Comment(4)
Yeah, except it totally forgets the "(without creating a new object)" part? Oh wait you can't do that. :PPhilbrook
fantastic response ughoavgfhwLoughlin
actually I'm noting with option 1 my update function is no longer re-usable (as it has to reference a specific property on the core data object). However option 2 & 3 aren't that great for me as it requires setting the number back in the caller. QUESTION - is there a way to have it so I can (a) have the update method reusable in terms of different NSNumber properties, BUT also (b) have the update function perform the update & not rely on the caller to set it afterwards?Loughlin
@Loughlin Sure, you could add an argument to the update method which tells it which key to use. I'll add this as an option 4.Beauteous

© 2022 - 2024 — McMap. All rights reserved.