Yes, generic typing is necessary whenever you need to write something that needs to operate on a number of types without knowing the type at compile time.
While objective-C doesn't contain generics per-se, Ids and void* are basically the same thing. You can write a method that takes in a void* or Id and do some processing on it. Before calling the method, you would do an explicit cast to a void* on the object you want to operate on.
Edit: For instance, what would you do if you wanted to write a method which makes a shallow copy of any typed object? You'd have to do something like copy(void* src,void* dest, int size)
. There is no way to do this without generics.