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

  • instanceObject (Instance object)
  • classObject (Class object)
  • meta-classObject (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)isaPoint to class objects (class)
  • Class object (class)isaPointing to a metaclass object (meta-class)
  • Metaclass objects (meta-clsaa)isaA metaclass pointing to a base class (meta-class)
  • The class objectsuperclassClass objects that point to the parent class (class), if there is no parent class,superclassA pointer tonil
  • Yuan class (meta-class)superclassA metaclass pointing to a parent class (meta-class), base class metaclasses (meta-class)superclassPoints to the base classclass
  • instanceCall method trace:isaFind class object, method does not exist, passsuperclasssFind the parent class, call the instance method of the parent class, and so on

Supplement:

  • Object methods, properties, member variables, protocol information, stored inclassIn the object
  • Class methods are storedmeta-classIn the
  • The value of the member variable is storedinstanceIn 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.