Objective-C Object Model and Application

Source: Internet
Author: User

Objective-C Object Model and Application

This article mainly introduces the implementation details of the Objective-C object model and the support for isa swizzling and method swizzling in the Objective-C object model. I hope this article will help you better understand Objective-C objects.

ISA pointer

Objective-C is an object-oriented programming language. Every object is an instance of a class. In Objective-C, each object has a pointer named isa pointing to the class of the object. Each class describes the characteristics of a series of its instances, including the list of member variables and the list of member functions. Each object can receive messages, and the list of messages that the object can receive is saved in its corresponding class.

Press Shift + Command + O in XCode, and then enter NSObject. h and objc. h. You can open the NSObject definition header file. Through the header file, we can see that NSObject is a struct containing the isa pointer, as shown in:

According to the design principles of object-oriented language, everything should be an object (strictly speaking, Objective-C does not fully implement this because it has simple variable types such as int and double ). In Objective-C, every class is actually an object. Each class also has a pointer named isa. Each class can also accept messages. For example, [NSObject alloc] sends a message named alloc to the NSObject class.

Press Shift + Command + O in XCode and enter runtime. h to open the Class definition header file. We can see through the header file that the Class is also a struct containing the isa pointer, as shown in. (In the figure, there are other member variables besides isa, but they are used to be compatible with the legacy logic of Objective-C in non-Version 2.0. You can ignore this variable .)

Because a class is an object, it must also be a real column of another class. This class is metaclass ). The metadata class saves the list of class methods. When a class method is called, The Meta class first checks whether it has the implementation of this class method. If not, the Meta class searches for this method from its parent class, until the inheritance chain header is found.

Metaclass is also an object. Where does the isa pointer of the metaclass point? To be fully designed, the isa pointer of all metaclass points to a root metaclass ). The isa pointer of the root metaclass itself points to itself, thus forming a closed loop. As mentioned above, the list of messages that an object can receive is saved in the corresponding class. In actual programming, we almost never encounter the situation of sending messages to the Meta class, so its isa pointer is rarely used in reality. However, this design ensures that object orientation is clean, that is, everything is an object and there is an isa pointer.

Let's take a look at the inheritance relationship. Because the class method is defined in metaclass, and the method calling rule is that if this class does not have a method implementation, to its parent class. Therefore, to ensure that the class method of the parent class can be called in the subclass, the Meta class of the subclass will inherit the Meta class of the parent class. In other words, class objects and metadata objects have the same inheritance relationship.

I would like to clarify the relationship, but this part is indeed a bit difficult. The figure below may make the relationship between isa and inheritance clearer.

In this figure, the most confusing thing is the Root Class. In implementation, the Root Class refers to NSObject. We can see that:

  1. The NSObject class includes its object instance method.
  2. The NSObject metadata includes its class methods, such as the alloc method.
  3. The NSObject metadata class inherits from the NSObject class.
  4. The methods in an NSObject class are also found by NSObject subclass during method search. Class member variables

    If you think of an instance of the class as a structure (struct) of C language, the isa pointer mentioned above is the first member variable of the structure, and other member variables of the class are arranged in the structure in sequence. Shows the order (picture from iOS 6 Programming Pushing the Limits):

    To verify this statement, we create a new project in XCode and run the following code in main. m:

     

    #import 
       
        @interface Father : NSObject {    int _father;}@end@implementation Father@end@interface Child : Father {    int _child;}@end@implementation Child@endint main(int argc, char * argv[]){  Child * child = [[Child alloc] init];  @autoreleasepool {      // ...  }}
       

     

    We will place the breakpoint at @ autoreleasepool and enter p * child in the Console. Then we can see that Xcode outputs the following content, which is consistent with the above statement.

     

    (lldb) p *child(Child) $0 = {  (Father) Father = {    (NSObject) NSObject = {      (Class) isa = Child    }    (int) _father = 0  }  (int) _child = 0}

     

    Variable and immutable

    Because the object layout in the memory can be regarded as a struct, the size of the struct cannot be changed dynamically. Therefore, the member variables cannot be dynamically added to the object at runtime.

    The method definitions of objects are stored in the Variable Area of the class. Objective-C 2.0 is not exposed in the header file, but in Objective-C 1.0, we can see that the definition list of a method is a pointer named methodLists (as shown in ). By modifying the pointer value to which the Pointer Points, You can dynamically add member methods to a class. This is also the principle of Category implementation. It also explains why Category can only add member methods for objects, but cannot add member variables.

    Note that the objc_setAssociatedObject and objc_getAssociatedObject methods can be used to add member variables to objects in disguise. However, because of the different implementation mechanisms, the object's memory structure is not actually changed.

    In addition to the object method, isa itself is also a pointer, so we can dynamically modify the isa pointer value at runtime to replace the entire object behavior. However, this application scenario is rare.

    System related API and application isa swizzling

    The implementation of KVO provided by the system uses the technology of dynamically modifying the value of the isa pointer. You can see the following description in Apple's document:

    Key-Value Observing Implementation Details

    Automatic key-value observing is implemented using a technique called isa-swizzling.

    The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table. This dispatch table essential tially contains pointers to the methods the class implements, among other data.

    When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class. as a result the value of the isa pointer does not necessarily reflect the actual class of the instance.

    You shoshould never rely on the isa pointer to determine class membership. Instead, you shoshould use the class method to determine the class of an object instance.

    Method Swizzling API description

    Objective-C provides the following APIs to dynamically Replace the implementation of class methods or instance methods:

    • Class_replaceMethod
    • Implementation of method_exchangeImplementations interchange two methods
    • Method_setImplementation: Set the implementation of one method.

      There are some minor differences between the three methods. We will introduce them as follows:

      • Class_replaceMethod can be seen in Apple's documents (as shown in). It has two different behaviors. When the class does not want to replace the original method, this method will call class_addMethod to add a new method for the class. Because of this, class_replaceMethod needs to pass in the types parameter during the call, method_exchangeImplementations and method_setImplementation are not required.

        • The internal implementation of method_exchangeImplementations is equivalent to calling the method_setImplementation method twice, which can be clearly understood from Apple's documents (as shown in)

          From the above differences, we can summarize the application scenarios of these three APIs:

          • Class_replaceMethod. You can use this method if the method to be replaced does not exist.
          • Method_exchangeImplementations, which is used when two methods need to be exchanged.
          • Method_setImplementation is the simplest method. It is used when you only need to set its implementation mode for a method.

            The source code of the above three methods is here. Interested parties can read them.

            Example

            When developing the client's note function, we need to use the system's UIImagePickerController. However, we found that, in the iOS6.0.2 system, the UIImagePickerController provided by the system has a screen conversion Bug on the horizontal screen of the iPad, resulting in a wrong direction. For details about specific bugs, see here.

            To fix this Bug, we need to replace the following two methods of UIImagePickerController:

             

            - (BOOL)shouldAutorotate;- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;

             

            We first implemented a class named ImagePickerReplaceMethodsHolder to define the method and implementation after replacement. As follows:

             

            // ImagePickerReplaceMethodsHolder.h@interface ImagePickerReplaceMethodsHolder : NSObject- (BOOL)shouldAutorotate;- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;@end// ImagePickerReplaceMethodsHolder.m@implementation ImagePickerReplaceMethodsHolder- (BOOL)shouldAutorotate {    return NO;}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {    return UIInterfaceOrientationPortrait;}@end

             

            Use of Open Source

            A few people who do not know the truth think that Apple will reject the App's use of the above APIs during the review, which is actually a misunderstanding of apple. It is safe to use the above APIs. In addition, the open source community also applies the above methods. For example:

            • The famous network library AFNetworking. AFNetworking network library (v1.x version) uses the class_replaceMethod method (105th rows of AFHTTPRequestOperation. m file)
            • Nimbus. Nimbus is a well-known tool library that provides NIRuntimeClassModifications. H files in its core module to provide encapsulation of the above APIs.
            • IOS client for public comment in China. The client uses the Wax-based WaxPatch developed by them. WaxPatch can dynamically modify the client logic through server updates. WaxPatch mainly modifies the wax_instance.m file in wax, and adds class_replaceMethod to replace the original implementation, so as to modify the original behavior of the client. Summary

              Through this article, we learned about the Objective-C language object model and the support for isa swizzling and method swizzling in the Objective-C language object model. This article also gives us a deeper understanding of the dynamic nature of the object model through specific instance code and open-source projects.

               

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.