Objective-C - The delegate subclass in the subclass

This is a rather complicated inheritance hierarchy, so bear me (I tried to simplify things, and not specify the exact case that I am using, which is even more difficult): -

Let's say I create a subclass of UITextField called TextField , which is my own custom general purpose extended text field. Now, to provide this enhanced functionality, in the init method of TextField , I set super.delegate = self so that all delegate methods from UITextField are sent to TextField . TextField implements the UITextFieldDelegate protocol and gets these delegate methods to do something interesting.

However, in turn, I want to make TextField have its own delegate. So I am creating a new protocol called TextFieldDelegate (note the lack of UI -prefix!) And give TextField ivar id<TextFieldDelegate> __weak delegate with the corresponding property so that other classes can get delegate methods from TextField .

I hope you are still with me, because so far I have not done anything complicated. But let me say that now I create another custom subclass of TextField , let it have PasswordTextField (in real life, you may not need to create a subclass just to implement the password function, but suppose there are some rather complex implementations that require this )

Suppose also that I want to make PasswordTextField (which, like TextField has a delegate property), can send an extended set of delegate methods. For example, it may be possible to send the passwordIsSecure method, which is sent after the password reaches the required level of complexity. Now, since this behavior was not found in the regular TextField , I am creating a new protocol: PasswordTextFieldDelegate <TextFieldDelegate> , which defines the new delegate methods for PasswordTextField and inherits all the delegation methods sent by TextField .

The problem is this: how to implement this in PasswordTextField ? Things that don't work:

Inheritance

I can’t just inherit the delegate from TextField because the TextField delegate matches only TextFieldDelegate and not PasswordTextFieldDelegate , so I can not send methods like [delegate passwordIsSecure] because TextFieldDelegate does not have such a method.

Override ivar

I could try to declare ivar in a PasswordTextField called a delegate, but the compiler complains that it is a duplicate declaration, because the superclass already has ivar called a delegate, so this also does not work *.

Superclass Change

I could go back to the TextField class and override the delegate to implement both TextFieldDelegate and PasswordTextFieldDelegate , but this seems messy and tells TextField that it can send PasswordTextFieldDelegate methods that of course cannot!

I have not tried this one, simply because it seems to violate all reasonable coding rules in the book.

So there must be some way to do this so that the subclass of the class can have its own delegate, which is a sub-delegate of the delegate of the superclass, and combine all this well, but I just can't figure it out! Any ideas?

(* As a side issue, I don’t understand why the compiler complains when PasswordTextField declares a duplicate of ivar with the name delegate, but does not complain when TextField declares a delegate with ivar, which is supposedly a duplicate of the UITextField property, called the delegate!)

+4
source share
3 answers

The UITextField ivar delegate is called _delegate, not the delegate. Therefore, why do you leave with declaring it again in TextField, but not in PasswordTextField.

Regarding the issue of delegation inheritance. I'm not sure that ObjectiveC supports what you want.

You just need to enter the delegate id, not 'id <TextFieldDelegate>'. Then you can override setDelegate and make sure the delegate passes according to ToProtocol. However, you would lose your compile-time checks and only check the execution time of the ToProtocol compliance command.

+1
source

So there you go! works .. and also has compilation warnings.

SimpleParent.h

 @protocol Parentprotocol <NSObject> @end @interface SimpleParent : NSObject { id<Parentprotocol> obj; } @property (retain) id<Parentprotocol> obj; @end 

SimpleParent.m

 #import "SimpleParent.h" @implementation SimpleParent @synthesize obj; @end 

SimpleChild.h

 #import <Foundation/Foundation.h> #import "SimpleParent.h" @protocol SimpleChildProtocol <Parentprotocol> @end @interface SimpleChild : NSObject @property (assign) id<SimpleChildProtocol> obj; @end 

SimpleChild.m

 #import "SimpleChild.h" @implementation SimpleChild @synthesize obj; @end 
+1
source

This is a rather confusing question, so forgive me if I miss the point, but it looks like your three different levels of inheritance have different requirements from your delegate, ergo each delegate will have to follow a different protocol, would it be a decision to keep each delegate level as otherwise named ivar and as another reference?

For example, your base class will have its own delegate , which, as you decide, will be assigned to the first inherited subclass. This one has its own delegate called level1delegate , and on the next level below there is another delegate called level2delegate . Of course, you could set all three of them to the same object if this object corresponded to all three protocols.

Basically, there is no rule that a delegate should be called "delegate," so don't tear yourself apart trying not to break it.

+1
source

Source: https://habr.com/ru/post/1390818/


All Articles