Wangzz Original address: http://blog.csdn.net/wzzvictory/article/details/8592492 reprint Please specify the source if you feel that the article is helpful, Please leave a message or follow the public account wangzzstrive to support me, thank you!
As a superset of the C language, object-oriented becomes the biggest difference between objective-c and C, so objects are one of the most important parts of objective-c. There are many object-oriented languages now, what is the difference between objects in objective-c and objects in other languages? The following is a brief introduction to the implementation of objects in objective-c.
1, objective-c in the class
Everyone knows that all objects are instantiated by their corresponding classes, but the class itself is also an object, do not be surprised by this sentence first.
Let's start by focusing on the classes in Objective-c. In Objective-c, almost all of the classes we use are subclasses of the NSObject class, and the NSObject class definition format is as follows (ignoring its method declaration):
@interface nsobject <NSObject> {
Class Isa;
}
What is this class? In objc.h we find that it is only a typedef definition of a struct (struct) pointer:
typedef struct OBJC_CLASS *class;
Similarly, what is Objc_class? In objective-c2.0, Objc_class is defined as follows:
struct Objc_class {
class Isa;
}
Write here people may faint, how to have an Isa?? What exactly are these Isa? What are the differences and connections between them? Then answer this series of questions.
In fact, any class definition in Objective-c is an object. That is, when the program starts, any class definition corresponds to a piece of memory. At compile time, the compiler generates one for each class and generates only a "object that describes its definition", which is the class object that Apple says is a singleton (singleton), and what we call an object in a language such as C + + is called an instance object ( Instance object). It's not hard to understand an instance object, but what does a class object do for food? We know that objective-c is a very dynamic language, so all instance objects (Instace object) in the program are generated at run time by the runtime library of Objective-c, and this class object Is the basis that the runtime library uses to create an instance object (instance objects).
to go back to the previous question, is it swollen? The ISA pointer to this instance object (instance object) points to the class object, which also has an Isa? The ISA of this class object (class Objec) is pointing to a objc-class, which is the "Meta-class object" (Metaclass objects), which is the same as the class object:
2. Class object
The essence of ① class object
We know that the class object is created by the compiler, the so-called class at compile time, that is, the class object (as the official document says: The class object is the compiled version of the Class). Any class that inherits NSObject directly or indirectly has an Isa pointer in its instance object (instance Objec) that points to its class object. This class object stores everything about the definition of the class that this instance object (Instace object) belongs to: including variables, methods, protocols, and so on. Thus, the class object can access all information about this class, which can be used to produce a new instance, but the class object cannot access the contents of any instance object.
When you call a "class method" such as [NSObject alloc], you are actually sending a message to his class object.
The difference between a ② class object and an Instance object
Of course there is a difference, although the class object retains the prototype of a class instance, but it is not the instance itself. It does not have its own instance variables and cannot execute methods of instances of those classes (only instance objects can execute instance methods). However, the definition of a class can contain methods that are deliberately prepared for class objects – class methods (not instance methods). Class objects inherit class methods from the parent class, just as the instance inherits instance methods from the parent class.
③ class object and class name
In the source code, the class object is represented by the class name.
In the following example, the Retangle class returns the version number of the class with a method inherited from the NSObject:
int versionnumber = [Rectangle version];
The class name represents the class object only as a recipient in the message expression. Elsewhere, you need to ask for an instance or class to return the class ID. Response Class Message:
ID AClass = [anobject class];
ID Rectclass = [Rectangle class];
As the above example shows, the class object is the same as the other object and is the ID type.
In summary, a class object is a fully functional object, so it can be dynamically recognized (dynamically typed), receive messages, and inherit methods from other classes. What is special is that they are created by the compiler and are missing their own data structures (instance variables), only the proxies that produce the instances at run time.
3, Meta-class objects (Metaclass object)
The essence of ① meta-class object
In fact, a class object is an instance of a meta-class object!! A meta-class describes a class object, just as a class object describes a normal object. The difference is that the method list of the meta-class is a collection of class methods that are responded to by the selector of the class object. When a message is sent to a class, objc_msgsend navigates to the Meta class through the ISA pointer of the class object and examines the list of methods of the meta-class (including the parent class) to determine which method to invoke. The meta class describes the class method instead of the class object, as if the class object describes the instantiation method instead of the instance object.
Obviously, the meta-class is also an object, and it should be an instance of another class, in fact the meta-class is an instance of the root class (root class ' s metaclass), and the root class is its own instance, that is, the ISA pointer to the root class points to itself.
The super_class of the class point to its parent class, while the super_class of the meta-class points to the meta-class of the parent class. The super class chain of a meta class is parallel to the super class chain of classes, so the inheritance of class methods is parallel to the inheritance of instance methods. The root class (root class ' s metaclass) Super_class points to the root class, so the entire pointer chain is linked!!
Remember that when a message is sent to any object, the method's check starts with the object's Isa pointer, and then the parent class. Instance methods are defined in a class, and class methods are defined in the Meta class and Root class. (the meta-class of the root class is the root class itself). In the principle of some computer languages, a class and meta-class hierarchy can be more freely composed, a deeper meta-class chain, and more instantiated classes that inherit from a single meta-class. The Objective-c class method is to use the root cause of the meta-class, and in other ways try to hide the meta-class. For example [NSObject class] is exactly equal to [nsobject self], so in form he still returns the Meta class that nsobject->isa points to. Objective-c language is a set of practical compromises.
Still some unidentified white? The following icon may help:
In summary, the class object contains the instance variable of the class, the definition of the instance method, and the meta-class object (Metaclass object) that includes the definition of the class method (that is, the static method in C + +). The class object and the meta-class object will of course contain something else, and Apple may add other things later, but for all we need to remember is that the class object holds information about the instance object (variables, instance methods, and so on), whereas the Meta-class object (Metaclass objects) stores information about the class ( The version of the class, Name, class method, etc.). It is important to note that the definition of the class object and the meta-class object (Metaclass object) are objc_class structures, which differ only in purpose, such as the list of methods in the Class object (instance objects) The instance method is saved in instance, and the class method is saved in the Meta-class object (Metaclass objects). For meta-class objects You can refer to the official Apple document "The Objective-‐c programming Language"
4. Related methods of class object and meta-class object
①object_getclass follows the ISA pointer of the instance, returns the class to which this instance belongs, the class is returned for the instance object (instance), and the Meta-Class (Metaclass) for the class.
The ②-class method returns the class for the instance object (instance), but does not return a meta-class (Metaclass) for the class, but only returns the class itself, that is, [@ ' instance ' class] returns __ Nscfconstantstring, and [NSString class] returns the NSString.
③class_ismetaclass can determine if a class is a meta-class.
④ uses Objc_allocateclasspair to create new classes and meta-class pairs at run time, use Class_addmethod and Class_addivar to add methods and instance variables to the class, and finally use OBJC_ Once the Registerclasspair is registered, you can use this class. See the dynamic language is a good place, you can change the already defined class when needed! Objective-c class method estimates that the bottom is how to achieve, but do not know why the class can not increase the instance variable, there are experts please leave a message.
OBJECTIVE-C provides us with two methods for initializing objects: The new method and the two-segment constructor that are available later in the objective-c2.0. Since you want to compare these two initialization methods, let's start with the similarities and differences between them.
One or two-segment construction method
This is a unique object creation method for Objective-c, written in the following form:
Nsstring*s=[[nsstring alloc] init];
The so-called two-segment construct, which refers to writing alloc and Init separately, is different from most other languages such as C, C + +, Java, and JavaScript. Let's take a look at what Alloc and init have done:
1. Alloc method
When an object is created, cocoa allocates enough memory for the object from the application's virtual address space. Cocoa iterates through all the member variables of the object, calculating the memory required by the type of the member variable.
When we create an object through the Alloc or Allocwithzone method, Cocoa returns an object that has not been "initialized". In the process, cocoa has done the following 3 things in addition to the above mentioned application for a large enough memory:
① Sets the reference count (Retain count) of the new object to 1.
② points the ISA member variable of the new object to its class object. The ISA member variable points to the class object that allocates memory, which is defined in the NSObject class, so that all objects that are cocoa are guaranteed to have this member variable. It is integrated with the OBJECTIVE-C runtime, which enables the cocoa object to be self-introspective (introspection) at run time.
③ sets the value of all other member variables of the new object to 0. (0 may refer to nil or 0 depending on the type of member variable)
④ returns a pointer to the object.
2. Init method
In most cases, we don't want all member variables to be zero, so
The ①init method does the real initial work of making the value of the member variable of the object conform to the initialization state in our program logic. For example, nsmutablestring may request an additional array of characters to dynamically modify the string.
② returns a pointer to the object that can be really used
Init also has a problem to be aware of, in some cases, Init will cause alloc of the original space is not enough, and the second time allocated memory space. So the following wording is wrong:
NSString *s=[nsstring alloc];
[s init];//the address that the Init returns here may change. The original pointer address of s may be an invalid address.
To do this, Apple introduced a programming code that lets you write Alloc and init in one line. So the code above is the correct notation
NSString *s=[[nsstring alloc] init];
Second, new method
Perhaps for consistency with other languages, Apple later introduced the new method to initialize the object. As new for the class method, it is simply equivalent to Alloc + init, but cannot specify the parameters of init, so it is seldom seen in actual use.
Iii. reasons for using the two-segment construction method
One might ask that the Objective-c object creation method is different from most other languages such as C, C + +, Java, JavaScript, and what causes Objective-c to do this design?
1. Historical reasons
There are some historical factors in this. Objective-c is a very old language. If you look at the documentation, you will find that it was born in the same era as C + + (1983 in two languages), and was launched as a C-oriented successor to the object. Of course, C + + wins eventually. Because the history is long, the objective-c also cannot have too many excellent language to make the reference, therefore, has many historical legacy design.
2. Design principles
Simply put, according to design pattern of single responsibility design principle, Apple think Alloc and Init is to do 2 different things, put these two things separate in 2 functions, for the programmer more clear. After a closer look at the documentation, I think this is due to historical reasons, so Apple feels that the Alloc method is too complex, historically, alloc not only allocates memory, but also specifies the memory partition (denoted by nszone) that memory resides in in detail.
At the same time, because the allocation and initialization phase is separate, the implementation of the initialization method only needs to deal with the variables of the new instance and completely ignores the problem of allocation, simplifying the process of initializing the method.
Iv. introduction of Nszone
Early Apple is recommended that programmers use Allocwithzone to manage memory allocations, each nszone represents a piece of memory partition, +allocwithzone: The (Nszone *) Zone method allows an object to allocate memory from a specified partition. The memory area is a feature of cocoa, which enables you to improve the performance of your program by keeping objects that are in use at the same time and adjacent objects in the address space of the computer in memory. To explain how an object's location in memory affects performance, you need to explain what happens when your application needs more memory than the physical memory.
Each cocoa application has a large addressable memory, and the operating system still provides memory when the application dynamically allocates memory, even if all of the computer's physical memory is already occupied. To meet this allocation requirement, the operating system uses page scheduling (paging) or exchange (swapping) operations to copy the contents of some physical memory to the hard disk, and the previously used physical memory can be provided for use, and the previous data should be written to the hard disk. If there is a portion of memory data that needs to be copied to the hard disk previously, the operating system copies another piece of physical memory to the hard disk and recalls the previous old memory back to memory. In the immediate presence of inter-drive scheduling, the operating system can still map address space to physical memory for each application. This function of the operating system is virtual memory.
The use of virtual memory can affect performance because scheduling from one physical memory disk to another is time consuming. Excessive page scheduling can degrade system performance, which is called jitter (thrashing). If two or more objects that are used together are far away in memory, the likelihood of jitter occurring is greatly increased, so the location of the memory allocation for the object instance is also important.
Partitions are used to ensure that memory allocated to objects that are used concurrently is in an adjacent location. When an object is needed, the other adjacent objects are also basically used, all the objects needed to call into memory at the same time more likely, when not required, but also can be recalled at the same time, the Nszone type in cocoa is the object that specifies the C structure that identifies the memory area, +allocwithzone: ( Nszone *) Zone method allows the Nszone variable to allocate memory from a specified partition. The purpose of reducing jitter has been achieved. It can be seen that the Apple designers of the good intentions!!!
Only, partitioning is a very low-level thing, and with the development of hardware devices, the increasing physical memory, and the complexity of operating system memory allocation functions, the original purpose of using partitions has gradually disappeared. Since the introduction of the garbage collection mechanism on Mac OS X 10.5, Apple does not recommend that programmers use Allocwithzone, in fact, the cocoa framework ignores +allocwithzone: (Nszone *) zone-specific partitions. Apple also mentions in the documentation that +allocwithzone: (Nszone *) zone is only a legacy design.
Objects such as objective-c objects and meta-class objects