Question

Is the concept of the Objective-C categories in anyway similar to the concept of mixins? If so: what are the similarities? In not: what are the differences?

Was it helpful?

Solution

To the best of my understanding:

Mixins

  • Syntactic sugar for composition
  • Added by the developer of the class, not the user
  • Can be reused by multiple classes
  • Can add instance variables
  • Can be implemented using forwarding in Objective-C

Categories

  • Similar to extension methods in other languages
  • Usually added by the user of the class, not the developer
  • Used by exactly one class and its subclasses
  • Can't add instance variables

OTHER TIPS

To be clear the answer is NO - they are not the same.

The differences are outlined by John Calsbeek in the accepted answer, but I would say the key difference is the one where mixins can be used in different classes, whereas categories always extend exactly one class - which they declare in their definition.

This is the key difference because it means the use cases for these two features are utterly different. Another way of looking at it is that, if you're coming from Ruby to Objective-C and missing your mixins, you won't find any joy with categories.

The use case for mixins is that you have some code - methods and instance variables - that you want to reuse in several classes that don't have a common superclass. You can't do that with categories.

Mixins are effectively "multiple-inheritance" of the type you don't find in Objective-C. The closest thing in objective-c is protocols, just as the closest thing Java is interfaces, but they have neither instance variables nor method bodies (in objective-C or java). So you're generally left with creating helper classes or putting code in superclasses.

The use case for objective-c categories is that you want to add methods to an existing class - even a system or library class.

I would say that mixins are more powerful, but since it's an apples-to-oranges comparison, it would be pointless.

To be accurate:

  • the Ruby equivalent of Categories, is to simply reopen the class you want to extend and extend it. (You can do that anywhere in Ruby, and it's effectively identical to Categories)

  • I'm not sure what the objective-c equivalent to Mixins is though - anyone?

[Update] A bit more searching, and no there isn't an equivalent of Mixins in Objective-C, but the enterprising Vladimir Mitrovic has created a library that effectively does it. https://github.com/vl4dimir/ObjectiveMixin

I'm in two minds as to whether to use it or not: sometimes if the language you're using doesn't support something, it's easier to work with it rather than fight it or try to import your favourite features from other languages. ("If you can't be with the programming language you love, love the one you're with").

Then again, perhaps that's just a bit to snooty of me. The whole Aspect Oriented Programming movement has been glomming features onto Java for years (but never gaining much traction, I might add, outside of JBoss). Anyway, Vladimir gets extra kudos for using Ninja Turtles in his example.

On another side node: as a relative objective-c noob, it seems to me that categories are way overused in sample code I find all over the web. It seems common practice to add static helper methods to system classes with categories, when it would be just as easy to create a helper class to house those methods in your project, with less risk of them breaking when the system class is updated or you import someone else's library with their own such categories. A common example is adding new static color methods to UIColor. Why not just add them to a local class?

The one really good use I've seen for categories is adding methods, not to system classes, but to generated classes. So when you generate classes from your core-data object model, and you want to add new constructors or other methods that really do belong in the model class, you can do it with categories, allowing you to safely regenerate the model class if you change your model, without losing your work.

In summary: - forget about categories as a solution for mixins - categories are good for core-data but overused and overrated otherwise

Categories are defined for a particular class, as far as I know, you can't create a category and add the methods it implements to several classes.

With a mixin, you might derive a new class from your base and the mixin, then instantiate this new class to take advantage of it.

With a category, you are effectively adding directly the base class, so that all instances of that base have access to the functionality provided by the category.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top