Let's say for example that I have MyUITextViewSubclass
which inherits from UITextView
and MyUITextFieldSubclass
which inherits from UITextField
and both of those subclasses contain a lot of the same methods and properties to add similar behavior to those UI controls.
Since UITextView
and UITextField
inherit from different classes, is there an easy way to create an abstract class to combine all of that repeated code? In other words, is it possible to create an abstract class that I could inherit from for both of those subclasses and then just override the methods that are different between the two?
What I know so far:
- I know Objective-C doesn't support multiple inheritance (inheritance from two or more classes)
- I know I could add common methods using Categories, but I don't think that solves overriding init methods or adding private properties
What you want is a mixin. This is not supported in Objective-C. Categories are no mixins, because they add an api to one class not to many (>1) classes. Using categories, what is not possible for many reasons as you said, would not help you.
The usual way to solve that problem is to create a helper class containing the additional code and use it in both classes.
Then you will find yourself typing
instead of
If this is really a problem, you can solve this with forward invocations. Just write a comment.
Building on Amin's answer, this is how you could do it:
Step 1: Create a
TextSurrogateHosting
protocol that will contain all the methods of yourUITextField
andUITextView
subclasses that you need to access from the methods that you want to add to both subclasses. This might for example be atext
andsetText:
method, so that your methods can access and set the text of either a text field or a text view. It might look like this:SPWKTextSurrogateHosting.h
Step 2: Create a
TextSurrogate
class that contains all the methods that you want to share between both theUITextField
and theUITextView
subclasses. Add those methods to a protocol so that we can use code completion in Xcode and avoid compiler warnings/errors.SPWKTextSurrogate.h
SPWKTextSurrogate.m
Step 3: Create your
UITextField
subclass. It will contain three necessary boilerplate methods to forward unrecognized method invocations to yourSPWKTextSurrogate
.SPWKTextField.h
SPWKTextField.m
Step 4: Create your
UITextView
subclass.SPWKTextView.h
SPWKTextView.m
Step 5: Use it:
This pattern should solve your problem. Hopefully :)
Some more background information is available here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105
No. It is not possible.
The closest thing you could achieve would be to manually add functionality to
UITextView
to make it mimicUITextField
. The obvious downside is that you must do this all manually, with your own code.Traits or Mixins are not supported by Objective-C, you only have built-in option of Categories. But fortunately Objective-C Runtime has almost all tools for implementing own idea if mixing or traits with adding methods and properties to your class at runtime. You can read more about opportunities which Objective-C Runtime provides for you on Apple's documentation website Objective-C Runtime Docs
The idea is:
1) You can create an Objective-C protocol (Mixin), in which you will declare properties and methods.
2) Then you create a class (Mixin implementation), which will implement methods from this protocol.
3) You make your some class, in which you want to provide the possibility of composition with mixins, to conform that protocol (Mixin).
4) When your application launches, you add with Objective-C runtime all implementations from (Mixin implementation) class and properties declared in (Mixin) into your class.
5) voilà :)
Or you can use some ready open source projects such as "Alchemiq"
You could use a preprocessor macro, but that is error-prone.