Why NSInteger instead of NSUInteger in "numberOfSectionInTableView:"?
Asked Answered
W

1

9

The UITableView data source method numberOfSectionsInTableView: has a return type of NSInteger. However, a UITableView cannot have a negative amount of rows; it has 0 or greater rows, so why is the return type of NSInteger? Doesn't that allow for crashes relating to a negative integer being returned?

Wilmerwilmette answered 28/10, 2012 at 2:34 Comment(5)
I don't think there's a good reason for it. It should be unsigned.Obrian
@Obrian - I agreed with you until I read borrrden's answer below.Wilmerwilmette
@stackmonster - Partially because I want to know if Apple was being careless and made a mistake assigning the return value type NSInteger, but mostly because I'm interested in the design of methods, and what would influence Apple engineers to make this particular method have this specific return type, which seemed counter-intuitive when I asked the question.Wilmerwilmette
I don't understand borrrden's answer at all. The number of sections can only be zero or higher. It should be an unsigned integer almost by definition. In the case of something like open(), -1 signifies an error condition so it does make sense -- having one invalid value for variables is handy, like NULL/nil for pointers.Obrian
It appears that Apple is trying to follow some kind of conventions of always using an NSInteger even when it doesn't make sense. The return type of these methods isn't as bad as the fact that they use NSInteger as the parameter type for numberOfRowsInSection, where a fairly common implementation might be to use the section as an index into an NSArray. When this happens, I have to manually typecast into an NSUInteger, as in [mySectionArray objectAtIndex:(NSUInteger)section], all because they pass in an NSInteger instead of an NSUIntegerFootstep
D
5

You can't do the check (if var < 0) return; with an unsigned integer. That is the standard reason for preferring one. Really the only reason to use an unsigned integer is if you need the extra room for larger digits, and you can guarantee the input will never try to be less than zero.

Defalcate answered 28/10, 2012 at 2:47 Comment(5)
I would argue that needing the extra room is irrelevant in decisions like this. If something can't possibly be a negative value, then it should be declared as an unsigned type. Apple can't even make the argument that this is why they've used NSInteger here: If that was their reason, then they should have also used NSInteger on NSArray count] and other NSArray methods.Footstep
@TimDean Consider this. Some daft user returns -1 from their numberOfSections method. Suddenly their table has billions of rows when it shouldn't. Why not just make it a signed integer and then say "hey dummy, you used a negative value"? I'm not saying this is how they did it but I think this is a valid reason for returning a signed int in instances when negative values make no sense. As for NSArray, Apple controls the entire pipeline there so there is no possibility of user error in returning an incorrect value.Defalcate
Seems like a stretch to justify it that way. Look no further than the numberOfRowsInSection method, where an NSInteger is passed in yet again. Apple controls the pipeline here and can be certain that no negative value is passed in, yet here they are passing in an NSInteger rather than an NSUInteger. In the end, I think that reasonable people can disagree in which strategy is best for any given case. But using an NSUInteger only when you need the extra room, I can't buy that and clearly Apple doesn't always go that way either.Footstep
@TimDean I agree that there is not a standard agreed upon reason to use one or the other. However, I disagree that apple controls the pipeline for numberOfRowsInSection. That is another data source method that a user can return from their own classes to affect a table view. I guess the way I see it is "why bother with an unsigned value when a signed value covers the valid range and is the default?"Defalcate
My reference to numberOfRowsInSection was specifically talking about the section index value that is passed in to the method, not about what it returns. Apple controls what is passed into that method via the section parameter, and yet it declares it as an NSInteger (making me do an annoying cast to NSUInteger if I happen to use that value as an index into an NSArray). My answer to "why bother" is simple: interfaces should be as self-explanatory as possible. If you never intend to support a negative value, don't make me research it by declaring it differently.Footstep

© 2022 - 2024 — McMap. All rights reserved.