Objective-c object model and its application

Source: Internet
Author: User



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 language object model. Hopefully this article will deepen your understanding of the Objective-c object.


Isa Pointer


Objective-c is an object-oriented programming language. Each object is an instance of a class. Within the Objective-c language, each object has a pointer to the object named Isa, which points to its class. Each class describes the characteristics of a series of its instances, including a list of member variables, a list of member functions, and so on. Each object can accept the message, and the list of messages that the object can receive is saved in the class it corresponds to.



By pressing SHIFT + Command + O in Xcode, and then entering NSObject.h and objc.h, you can open the NSObject's definition header file, and with the header file we can see that the nsobject is a struct that contains the ISA pointer, as shown in:





According to the design principle of object-oriented language, all things should be objects (strictly speaking, objective-c does not do this completely, because it has simple variable types such as int, double). In the Objective-c language, each class is actually an object. Each class also has a pointer named Isa. Each class can also accept messages, such as [NSObject alloc], which is to send a message named Alloc to the NSObject class.



By pressing SHIFT + Command + O in Xcode, and then entering runtime.h, you can open the class's definition header file, and with the header file we can see that class is also a struct that contains the ISA pointer, as shown in. (There are other member variables in the figure except for Isa, but that is to be compatible with the legacy logic of non-version 2.0 objective-c, which you can ignore.) )





Because a class is also an object, it must also be a real column of another class, which is a meta-class (Metaclass). The Meta class holds a list of class methods. When a class method is called, the meta-class first looks for the implementation of the class method itself, and if not, the meta-class finds the method to its parent class until the header of the inheritance chain is found.



A meta-class (Metaclass) is also an object, so where does the meta-class's Isa pointer point? For completeness of design, all of the meta-class Isa pointers point to a root class (root metaclass). The root class (root metaclass) itself has the ISA pointer pointing to itself, which makes the line a closed loop. As mentioned above, the list of messages that an object can receive is stored in its corresponding class. In actual programming, we rarely encounter the case of sending a message to the Meta class, and its Isa pointers are seldom used in practice. However, this design guarantees object-oriented cleanliness, that is, everything is an object and has an Isa pointer.



Let's look at inheritance, because the definition of a class method is saved in a meta-class (Metaclass), and the rule of a method call is that if the class does not have an implementation of a method, it continues to find its parent class. Therefore, in order to ensure that the class method of the parent class can be called in the subclass, the subclass class inherits the meta-class of the parent class, in other words, the class object and the meta-class object have the same inheritance relationship.



I would like to clarify the relationship, but this piece is really a bit around, the following picture may be able to let you to the ISA and inheritance of a clear relationship





The most confusing thing about this diagram is the root class. In the implementation, Root class refers to NSObject, which we can see:


    1. The NSObject class includes its object instance methods.
    2. NSObject's meta-class includes its class methods, such as the Alloc method.
    3. The NSObject meta-class inherits from the NSObject class.
    4. A method in a NSObject class is also found by the NSObject subclass when it finds the method.
member variables of the class


If you consider an instance of a class as a C-language struct (struct), the ISA pointer above is the first member variable of the struct, and the other member variables of the class are sequentially arranged in the struct. The order of arrangement is shown (image from IOS 6 programming pushing the Limits):





To verify this, we create a new project in Xcode and run the following code in MAIN.M:




 
#import <UIKit/UIKit.h>

@interface Father : NSObject {
    int _father;
}

@end

@implementation Father

@end

@interface Child : Father {
    int _child;
}

@end

@implementation Child

@end


int main(int argc, char * argv[])
{

  Child * child = [[Child alloc] init];
  @autoreleasepool {
      // ...
  }
}




We put the breakpoint at the @autoreleasepool, and then enter P *child in the console, you can see the Xcode output as follows, which is consistent with what we said above.




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


Because the arrangement of an object in memory can be seen as a struct, the size of the structure does not change dynamically. Therefore, you cannot dynamically add member variables to an object at run time.



In contrast, the method definition of an object is saved in a variable region of the class. OBJECTIVE-C 2.0 does not expose the implementation in the header file, but in Objective-c 1.0 we can see that the definition list of the method is a pointer to a pointer named Methodlists, as shown in. By modifying the value of the pointer pointed to by the pointer, you can implement dynamically adding member methods to a class. This is also the principle of category implementation. It also explains why the category can only add member methods to objects, but cannot increase member variables.





In particular, the Objc_setassociatedobject and Objc_getassociatedobject methods can be used to add member variables to an object in a disguised way, but because of the implementation mechanism, it does not really change the memory structure of the object.



In addition to the object's methods can be modified dynamically, because ISA itself is only a pointer, so we can also dynamically modify the value of the ISA pointer at runtime, to replace the object of the entire behavior. However, this scenario is less.


system-related APIs and Applicationsapplication of ISA swizzling


The implementation of the KVO provided by the system takes advantage of the technique of dynamically modifying the value of the ISA pointer. The following description can be found in Apple's documentation:



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 essentially contains pointers to the methods of the class implements, among other data.



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



You should never rely on the ISA pointer to determine class membership. Instead, you should 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 a class method or an instance method:


    • Definition of Class_replacemethod substitution class method
    • Implementation of 2 methods for method_exchangeimplementations Exchange
    • Method_setimplementation setting 1 implementations of methods


There are some subtle differences between the 3 methods, which are described below:


    • Class_replacemethod can be seen in Apple's documentation (as shown), and it behaves in two different ways. When there is no original method in the class to replace, the method calls Class_addmethod to add a new method to the class, and because of this, Class_replacemethod needs to pass in the types parameter when called, and Method_ Exchangeimplementations and method_setimplementation don't need it.



    • The internal implementation of method_exchangeimplementations is equivalent to calling 2 Method_setimplementation methods, which are clearly understood in Apple's documentation (as shown)




From the above differences we can summarize the usage scenarios of these 3 APIs:


    • Class_replacemethod, you can consider using this method when the method that needs to be replaced may have a situation that does not exist.
    • Method_exchangeimplementations, used when an implementation of 2 methods needs to be exchanged.
    • Method_setimplementation The simplest usage when you just need to set its implementation for a method.


The source of the above 3 methods here, interested students can read.


using the example


We need to use the uiimagepickercontroller of the system when we develop the client's note function. However, we found that under the iOS6.0.2 system, the system provided by the Uiimagepickercontroller in the ipad horizontal screen has a screen of the bug, causing its direction error. Specific bug details can be found here.



To fix this bug, we need to replace Uiimagepickercontroller with the following 2 methods




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




We first implemented a class named Imagepickerreplacemethodsholder, which defines the replacement method and implementation. As shown below:




 
// 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 the open source world


A small number of unidentified students think that Apple will refuse to use the API when the audit, which is actually a misunderstanding of Apple. It is safe to use the API as above. In addition, the open source community is also appropriate for the use of the above methods. For example:


    • The famous network library afnetworking. The Afnetworking Network library (v1.x version) uses the Class_replacemethod method (line 105th of the afhttprequestoperation.m file)
    • Nimbus. Nimbus is a well-known tool library that provides a NIRuntimeClassModifications.h file in its core module for encapsulation of the above API.
    • The domestic public reviews iOS client. The client uses their own wax-based modified waxpatch,waxpatch to enable the dynamic modification of the client's logic through server updates. Waxpatch mainly modifies the wax_instance.m file in wax, in which the Class_replacemethod is added to replace the original implementation, thereby modifying the client's original behavior.
Summary


In this article, we learned about the object model of the Objective-c language and the support for ISA swizzling and method swizzling in the Objective-c language object model. This article also through the concrete example code and the open source project, let us to this object model provides the dynamic nature to have the deeper understanding.



Objective-c object model and its application


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.