OC to C/C++
We all know that most objective-C code we write is actually C++ code.
Objective-c is compiled in objective-C –> C/C++ –> assembly –> machine language.
So objective-C object orientation is based on C\C++ data structure implementation;
What would a C++ file look like if you wanted to see it? We can use commands to convert OC code to C/C++ code. The command line is as follows:
Xcrun -sdk iphoneOS clang-arch arm64 -rewrite-objc OC source file -o Output CPP fileCopy the code
How is an OC object laid out in memory?
Take NSObject, create an object NSObject *obj = [[NSObject alloc]init]; Press CMD to view directly
@interface NSObject <NSObject> { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-interface-ivars" Class isa OBJC_ISA_AVAILABILITY; #pragma clang diagnostic pop }Copy the code
Seeing only a Class isa, convert it to a C++ file and look again:
struct NSObject_IMPL {
Class isa;
};
Copy the code
Yes, OC objects are stored in memory as structures after they are converted to C++ code. An object may have multiple properties of different types, so it is stored as a structure.
For structures, it’s the same as for arrays. The address of its first member is the address of the structure object. So the address of an OC object is actually the address of its ISA pointer.
What if there were more than one member in this class?
@interface Cat : NSObject
{
NSString *_name;
int _age;
}
@end
@implementation Cat
@end
Copy the code
After the transformation:
struct Cat_IMPL { struct NSObject_IMPL NSObject_IVARS; NSString *_name; int _age; }; Struct NSObject_IMPL {Class isa; struct NSObject_IMPL {Class isa; }; Struct Cat_IMPL {Class isa; NSString *_name; int _age; };Copy the code
So when you execute the following code:
Cat *cat = [[Cat alloc]init];
cat->_age = 10;
cat->_name = @"Tom";
Copy the code
The cat instance object is a pointer to a struct Cat_IMPL structure. This memory space stores the values of the individual member variables of the instance object;
The address of the memory space is the address of the first element of the memory space Class ISA; The isa pointer points to a class object of the Cat class.
Struct Cat_IMPL (int Cat_IMPL);
Cat *cat = [[Cat alloc]init]; cat->_age = 10; cat->_name = @"Tom"; struct Cat_IMPL *catImpl = (__bridge struct Cat_IMPL *)cat; NSLog(@"name is %@, age is %d", catImpl->_name, catImpl->_age); Result: Name is Tom, age is 10Copy the code
So the Cat class, converted to C++, is struct Cat_IMPL, and the Cat pointer points to one of these structures.
How much space does the instance object take up?
The memory footprint of cat is also obvious: an ISA pointer is 8 bytes, a name pointer is 8 bytes, and an int is 4 bytes, so this object only needs 20 bytes to store. Is that true?
Structs also have their own alignment, structs are all integer multiples of the maximum member size, but for struct alignment purposes, there are 8*3 = 24 bytes;
However,OC has its own alignment. When iOS allocates memory, it always allocates 16 * N to facilitate fast CPU access, so the cat object actually allocates 32 bytes.
View the ways to occupy space:
Class_getInstanceSize ([NSObject class]) How much memory is actually allocated to create an instance object malloc_size((__bridge const void *)obj)Copy the code
Objects in OC
There are three main categories
instance
Object (Instance object)class
Object (Class object)meta-class
Object (metaclass object)
Instance objects
It’s an object that comes out of the class alloc, and every time you call that alloc it creates a new instance object
Create two instance objects
NSObject *obj1 = [[NSObject alloc]init];
NSObject *obj2 = [[NSObject alloc]init];
Copy the code
Obj1 Obj2 is two different objects occupying two different memory. A class can have multiple instances in memory.
Instance objects store information in memory including isa Pointers and values of other member variables
Class object
Each class has only one class object and only one metaclass object.
Class objectClass1 = [obj1 Class]; Class objectClass2 = object_getClass(obj1); Class objectClass3 = [NSObject class]; NSLog(@"objectClass1 = %p",objectClass1); NSLog(@"objectClass2 = %p",objectClass2); NSLog(@"objectClass3 = %p",objectClass3); ObjectClass1 = 0x7ffF88a67e08 objectClass2 = 0x7ffF88a67e08 objectClass3 = 0x7fff88a67e08Copy the code
The class method always returns a class object
Class method source:
- (Class) {return self->isa; } + (class){ return self; }Copy the code
verify
Class objectClass4 = [[NSObject class]class]; Class objectClass5 = [[[NSObject class]class]class]; NSLog(@"objectClass4 = %p",objectClass4); NSLog(@"objectClass5 = %p",objectClass5); ObjectClass4 = 0x7FFF88A67e08 objectClass5 = 0x7FFF88A67e08Copy the code
Class objects mainly include: ISA pointer, superclass pointer, attribute information, object method information, protocol information, member variable information
Yuan class object
Metaclass objects and class objects have the same memory structure, but not the same purpose. It also includes:
Isa pointer, Superclass pointer, property information, object method information, protocol information, member variable information
Class objectMetaClass = object_getClass([NSObject class]); ObjectMetaClass is a meta-class object of NSObject.Copy the code
Each class has one and only one meta-class object in memory
Add:
object_getClass(id obj)
The obJ passed in May be an instance object, a class object, or a meta-class object
The return value:
-
If it is an instance object, return a class object
-
If it is a class object, return a meta-class object
-
If it is a meta-class object, return the meta-class object of NSObject
The relationships among instance objects, class objects, and metaclass objects
To talk about the relationship between the three, you have to mention that picture circulating on the Internet
In general:
- Instance object (
instance
)isa
Point to class objects (class
) - Class object (
class
)isa
Pointing to a metaclass object (meta-class
) - Metaclass objects (
meta-clsaa
)isa
A metaclass pointing to a base class (meta-class
) - The class object
superclass
Class objects that point to the parent class (class
), if there is no parent class,superclass
A pointer tonil
- Yuan class (
meta-class
)superclass
A metaclass pointing to a parent class (meta-class
), base class metaclasses (meta-class
)superclass
Points to the base classclass
instance
Call method trace:isa
Find class object, method does not exist, passsuperclasss
Find the parent class, call the instance method of the parent class, and so on
Supplement:
- Object methods, properties, member variables, protocol information, stored in
class
In the object - Class methods are stored
meta-class
In the - The value of the member variable is stored
instance
In the object
Why does a superclass pointer to a base metaclass point to a base class object when no method is found?
This is because OC is actually converted to C/C++ to remove the underlying implementation when calling methods; However, the underlying implementation of C/C++ does not have a classification method or object method that does not distinguish between + – signs
For example, [NSObject test] actually converts to
objc_msgSend([NSObject class], @selector(test))
Copy the code
There is no distinction between the + – sign, so after the base class metaclass object does not find the corresponding class method, it will go to the base class object to check whether there is an object method with the same name, if there is, it will call, if there is no more, it will enter dynamic method parsing, message forwarding or directly error.
If there is any mistake above, welcome to correct. Please indicate the source of reprint.