Here are a few methods from some Apple classes:
- (NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID;
- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
+ (id)insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context
It is reasonable to expect all of these methods to return subclasses of the return type. Due to this the returned object is often assigned to a variable of the expected type, eg:
BCCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[BCCustomTableViewCell cellIdentifier]];
This makes the compiler unhappy; a cast solves this, but casting like this is dirty:
BCCustomTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:[BCCustomTableViewCell cellIdentifier]];
However, when the return type is id
, this cast can be removed, albeit at the cost of some type safety, resulting in my code being cleaner:
BCPerson *person = [NSEntityDescription insertNewObjectForEntityForName:BCPersonEntityName inManagedObjectContext:context];
Personally, I prefer it when the return type is id
. Is there any rationale that Apple used for choosing one approach over the other, or is it simply due to the preference of the developer who wrote the methods?
In the three examples you describe, two different principles are at work:
In the two first, Apple wants you to use a cast as a "I know what I'm doing" sort of thing: When you are accessing a generic object through an identifier, you might end up being surprised by the class of the return value, unless you know what you're doing.
In the latter example, the method is essentially a factory method, equivalent to alloc init
, and in most cases you had better know what it is you are making.
In other words, to answer your question:
For a factory method, id
, for a getter, the same as the setter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With