Well, I think it can be described using a very contrived example. Let's say you have a method in Java which prints out all of the elements in an ArrayList:
void foo(ArrayList list)
{
for(int i = 0; i < list.size(); ++i){
System.out.println(list.get(i).toString());
}
}
Now, if you call that method like so: someObject.foo(NULL); you're going to probably get a NullPointerException when it tries to access list, in this case in the call to list.size(); Now, you'd probably never call someObject.foo(NULL) with the NULL value like that. However, you may have gotten your ArrayList from a method which returns NULL if it runs into some error generating the ArrayList like someObject.foo(otherObject.getArrayList());
Of course, you'll also have problems if you do something like this:
ArrayList list = NULL;
list.size();
Now, in Objective-C, we have the equivalent method:
- (void)foo:(NSArray*)anArray
{
int i;
for(i = 0; i < [anArray count]; ++i){
NSLog(@"%@", [[anArray objectAtIndex:i] stringValue];
}
}
Now, if we have the following code:
[someObject foo:nil];
we have the same situation in which Java will produce a NullPointerException. The nil object will be accessed first at [anArray count] However, instead of throwing a NullPointerException, Objective-C will simply return 0 in accordance with the rules above, so the loop will not run. However, if we set the loop to run a set number of times, then we're first sending a message to anArray at [anArray objectAtIndex:i]; This will also return 0, but since objectAtIndex: returns a pointer, and a pointer to 0 is nil/NULL, NSLog will be passed nil each time through the loop. (Although NSLog is a function and not a method, it prints out (null) if passed a nil NSString.
In some cases it's nicer to have a NullPointerException, since you can tell right away that something is wrong with the program, but unless you catch the exception, the program will crash. (In C, trying to dereference NULL in this way causes the program to crash.) In Objective-C, it instead just causes possibly incorrect run-time behavior. However, if you have a method that doesn't break if it returns 0/nil/NULL/a zeroed struct, then this saves you from having to check to make sure the object or parameters are nil.
You should use the arc4random_uniform()
function. It uses a superior algorithm to rand
. You don't even need to set a seed.
#include <stdlib.h>
// ...
// ...
int r = arc4random_uniform(74);
The arc4random
man page:
NAME
arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdlib.h>
u_int32_t
arc4random(void);
void
arc4random_stir(void);
void
arc4random_addrandom(unsigned char *dat, int datlen);
DESCRIPTION
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8
bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo-
random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and
random(3).
The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via
arc4random_addrandom().
There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically
initializes itself.
EXAMPLES
The following produces a drop-in replacement for the traditional rand() and random() functions using
arc4random():
#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))
Best Solution
You can declare multiple methods:
In the implementation you can do this:
Edit:
Please do not use
print
andprint:
at the same time. First of all, it doesn't indicate what the parameter is and secondly no one (ab)uses Objective-C this way. Most frameworks have very clear method names, this is one thing that makes Objective-C so pain-free to program with. A normal developer doesn't expect this kind of methods.There are better names, for example: