Jason George Jason George - 1 year ago 104
Objective-C Question

Using (id) in Objective-C

I have a function that I want to operate on two different custom objects. My first thought was to accept the argument as an (id) and operate on the id object. I can't quite seem to figure out how to do that, however.

Both classes (say apples and oranges) have interface variables:

NSDecimalNumber *count;

I want to do something similar to this:


return [count decimalNumberByAdding:addObject.count];

I can't seem to figure out the syntax to make that happen. Is this the proper approach, or would it be better to subclass (from say a fruit class) and operate on the parent class?


return [count decimalNumberByAdding:addFruit.count];

Answer Source

While you can send a message to any object (id) - property accessors require that the compiler be aware of the type you are dealing with - this is because property accessors are syntactic sugar around calling specific getter and setter methods.

You have a few of ways of working around this:

  1. Instead of accessing the count property, call the corresponding [getCount] methods.

  2. If the different classes have different versions of this method, you can use a runtime type check:

  3. Provide a base class for both types so that you can pass in something more specific than (id).

  4. Define and implement a Protocol that both objects implement that defines a count property (or method).

Example of a dynamic type check:

if( [object isKindOfClass:[Apple Class] )
   // call one overload of getCount
else if( [object isKindOfClass:[Orange Class] )
   // call another overload of getCount

Personally, I favor strong typing in my code because it makes it easier to understand the intent. It also allows the IDE to support your coding effort with intellisense, static analysis, and refactoring features. So, in your case, I would use either #3 or #4 as an approach - depending on whether inheritance is really appropriate for the problem.