Can I make an NSInteger an optional parameter on a method?

Go To


I would like to have a method along the lines of

setData:(SomeClassName *)data inPosition:(NSInteger)position

and in the implementation, check for nil as position. The idea is that if the position is provided, I will use it, and if not, I will allocate it automatically.

The problem is I can't pass either NULL or nil into this without a compiler warning.

I believe I have seen this pattern elsewhere (optional parameters). I think it might have been related to an NSIndexPath.

Should I use an NSNumber as a wrapper? or is there some other secret?

As an aside, I considered using separate methods - setData: and setData:inPosition:. But the problem is that 'data' is a core data created attribute, not a regular ivar, so when I actually want to set the value I would have to remember to send all the KVO messages. For example, inside setData:withPosition, I can't call the standard setData: - it would overwrite any work I did with the position.

Would also be interested in knowing which is the 'better' solution of these two.

2012-04-04 02:38
by Ben Packard
use NSNumber or overloa - mshsayem 2012-04-04 02:46
There is no overload in Objective-C - Rob Napier 2012-04-04 03:11


@Justin's approach is generally the most appropriate. However, to your question about setData: and KVO, there are several things to note:

  • KVO notifications are sent automatically as long as the method is named setFoo:. Even if you override setFoo:, KVO will wrap your implementation with the correct KVO notification calls for the property. This is very likely the most magical thing in Cocoa. (I used to be certain it was the most magical thing, but I'm starting to wonder about block variable scoping, and especially how blocks are moved from the stack to the heap; that may be more magical.)

  • If you need to set a Core Data attribute directly, bypassing KVO and every other piece of possible magic, you can use the primitive accessor. setPrimitiveData: is the underlying method that setData: uses to set the property. You should not override the primitive accessors.

@Justin appears to have deleted his answer. The typical solution here would be to declare setData: and setData:inPosition: (btw, as a reader, I have no idea what "inPosition" means. I hope that it makes sense in context). setData: would call setData:inPosition: applying whatever is necessary to figure out "position."

2012-04-04 02:53
by Rob Napier
Wow that is magical. Who knew (well, you did). Yes, when I mentioned KVO I meant to also include the setPrimitiveData: method. So I customize the default setData: to figure out a position, and then send it on to setData:inPosition. But inside setData:inPosition, I need to actually, y'know, set the data. If I do this using setData: it will recalculate 'position' and send it back to setData:inPosition:, which in turn uses setData: - well you get the idea. Or are you saying I should not use the standard setData: to actually set the data, and instead use setPrimitveData: - Ben Packard 2012-04-04 03:21
Correct. The one trick here is whether you want KVO to post from setData:inPosition:. If so, you'll need to post it yourself, and suppress it from setData:. You do that by overriding +automaticallyNotifiesObserversForKey:, and returning NO for data - Rob Napier 2012-04-04 03:25 - Rob Napier 2012-04-04 03:26
Ok I think I follow. So, I think I should probably fire the KVOs inside setData:inPoition: since setData: will always forward here, and it's where I want to actually set the primitive? It seems pointless at best (and side-effecty at worst) to allow it to happen twice. But because of the 'magic', my setData: will also try to send KVO because 'data' is the name of the attribute. Which is why I override + automaticallyNotifiesObserversForKey: Let me know if I messed up. Thanks so much for the insight - Ben Packard 2012-04-04 03:40
Sounds like you got it - Rob Napier 2012-04-04 03:44
@RobNapier Yes, it lasted only a few minutes. Sorry. I did not address KVO in my answer. I hadn't read that far, then got I distracted and deleted it. Take anything you like from it. + - justin 2012-04-04 03:46
Thanks all, couldn't have asked for more - Ben Packard 2012-04-04 03:51


Using the NSNumber wrapper is pretty standard.

Of course, you could always pass -1, NSNotFound, or define your own n/a value too.

2012-04-04 02:41
by lnafziger


There are three options:

  1. Pass -1 or some such for "no value"
  2. Use an NSNumber wrapper and pass nil for "no value"
  3. Overload

You could try to use the Objective-C optional parameter mechanism, but that requires some sort of sentinel to mark the end of the list, so it's no better than any of the others.

2012-04-04 03:12
by Hot Licks