"Multi-inheritance" of objective-C"

Source: Internet
Author: User

"Multi-inheritance" of objective-C"

 

When single inheritance is not enough and it is difficult to model the problem domain, we usually think of Multi-inheritance directly. Multi-inheritance is the ability to derive from an additional direct base class, which can be more directly modeled for the application. However, objective-C does not support multi-inheritance. Because the message mechanism name search occurs at runtime rather than during compilation, it is difficult to solve the problem of Ambiguity Caused by multiple base classes. However, objective-C does not need to support multi-inheritance. We can find the following methods to indirectly implement multi-inheritance:

  • Message forwarding
  • Delegate and Protocol
  • Category
Message forwarding

When a message is sent to someobject, but the implementation of the corresponding method cannot be found in the current class and parent class, the runtime system does not immediately report an error and cause the program to crash, instead, perform the following steps in sequence:



Briefly describe the process:

1. Dynamic Method Analysis
Send the resolveinstancemethod signal to the current class and check whether the method is added to the class dynamically. (Confused, please search: @ dynamic) 2. Fast message forwarding


Check whether the forwardingtargetforselector method is implemented for this class. If yes, call this method. If the returned object of this method is not nil or not self, the message is resent to the returned object.

3. Standard Message forwarding


Runtime sends methodsignatureforselector: gets the method signature corresponding to the selector. If the returned value is not null, the system forwards the message through forwardinvocation. If the returned value is null, the system sends the doesnotrecognizeselector: Message to the current object. The program crashes and exits.

 

As the name suggests, we can use two or three methods in the above process to complete message forwarding. Fast message forwarding

The implementation of fast message Forwarding is simple. You only need to override the-(ID) forwardingtargetforselector :( SEL) aselector method.

Let me give you a simple example. For example, there are two classes: Teacher and Doctor. Doctor can be operated (operate method ).
@interface Teacher : NSObject@end

@interface Doctor : NSObject- (void)operate;@end
Through fast message forwarding, teacher can easily call the doctor Method for surgery.



The teacher Class must forward messages to the doctor:
- (id)forwardingTargetForSelector:(SEL)aSelector{    Doctor *doctor = [[Doctor alloc]init];if ([doctor respondsToSelector:aSelector]) {return doctor;}return nil;}
Although messages can be dynamically forwarded and transmitted, the static check in the editor cannot be bypassed. The problem arises. How should we declare that the teacher class does not implement the operate method?
So far, I have only thought of the following two methods:

Declaration method 1 ---- category

@interface Teacher (DoctorMethod)- (void)operate;@end

Method 2 ---- import the header file and type conversion during call


The header file of the teacher Class must contain the doctor header file, which tells the compiler to find the operator method declaration in the Doctor. h file and forcibly convert the type when calling the file.

    Teacher *teacher = [[Teacher alloc]init];    [(Doctor *)teacher operate];

If you are interested, you can think about a problem: If you convert its type to ID, you can also compile it and implement forwarding. But what are the risks?



Method 1 is clear and easy to use. Why do we need to propose method 2? My idea is that the disadvantage of method 1 is that the method thrown out is fixed, and in. H is shown in; method 2 is relatively flexible and hides the messages I want to forward.







Standard Message forwarding

Standard Message forwarding requires rewriting of methodsignatureforselector: And forwardinvocation: two methods.

Sending process:
Rewrite forwarding method:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{    NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];    if (signature==nil) {        signature = [someObj methodSignatureForSelector:aSelector];    }    NSUInteger argCount = [signature numberOfArguments];    for (NSInteger i=0 ; i<argCount ; i++) {    }        return signature;}- (void)forwardInvocation:(NSInvocation *)anInvocation{    SEL seletor = [anInvocation selector];    if ([someObj respondsToSelector:seletor]) {        [anInvocation invokeWithTarget:someObj];    }    }
Comparison of Two message forwarding Methods




Fast message forwarding: simple, fast, but only forwards messages to one object.


Standard Message forwarding: it is relatively complex and slow, but the forwarding operation is controllable and can forward multiple objects.

Delegate and Protocol

Delegate is the most common callback mechanism in objective-C. I think there is nothing to say about the usage. Summarize the features of this mechanism:

  • The delegate assists the subject in completing the operation tasks and reserves the customized operations to the delegated object for custom implementation, similar to subclass-based subjects.
  • In addition, it can be used as an event listener.
  • I can't think of it for a moment...







Category

I personally think that category is the essence of objective-C design and the biggest reason why I fall in love with objective-C.

A category is a powerful feature that can be used to add methods or instances to a class. There must be a lot of people who don't agree. I 'd like to remind you that one of the limitations of the category is that you cannot add new instance variables to the class. The endorsement is really broken. Let me give you an example.



Repeat another teacher class:

@interface Teacher : NSObject{    NSUInteger age;}@end
If you have an age, you cannot describe teacher. I want to add a certain sion instance to save Teacher's major. The intuitive idea is to subclass the teacher, which can also be used. You Need To Know About runtime programming, and pay attention to objc_setassociatedobject and objc_getassociatedobject.
////  Teacher+Profession.m//  #import "Teacher+Profession.h"#import <objc/runtime.h>const char *ProfessionType = "NSString *";@implementation Teacher (Profession)-(void)setProf:(NSString*)prof{    objc_setAssociatedObject(self, ProfessionType, prof, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}-(NSString *)prof{    NSString *pro = objc_getAssociatedObject(self, ProfessionType);    return pro;}@end
Now, you can use setprof: and Prof to access the permission sion value of teacher.

Conclusion

I am very willing to see your feedback. Any correction, criticism, and improvement plans will allow us to make progress together.

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.