1: the nature of the Objective – C
Objective’s underlying code is implemented in C/C++, so Objective-C object orientation is implemented based on C/C++ data structures.
willOC
File compiled intoC++
File in commonOne of two ways
:
One is Clang and the other is XCRun.
- clang:
clang -rewrite-objc main.m -o main.cpp
- xcrun:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
Xcode is installed with the xcrun command, which is wrapped around clang to make it easier to use
2: The nature of objective-C objects
You can create a new project and create an object called Person inside the main function with the name attribute, as shown below.
@interface Person : NSObject @property (nonatomic, strong) NSString *Name; @end @implementation Person @end int main(int argc, const char* argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!" ); } return 0; }Copy the code
Then convert main.m to main.cpp with the xcrun-sdk iphoneOS clang-arch arm64-rewrite-objc main.m -o main.cpp. Next, we extract key information from main.cpp.
1: The underlying nature of objects isThe structure of the body
inmain.cpp
Search for the name of the object we just createdPerson
, you’ll find the following code
So we assume that objects are essentially structures at the bottom. So what is NSObject_IMPL? We continue our search at main. CPP and find that NSObject_IMPL is the structure that holds the ISA pointer.
2: in the objectOC
Level inheritanceNSObject
At the bottom, it actually inheritsobjc_object
We first searched for NSObject and found the following code
typedef struct objc_object NSObject;
Person inherits from objC_Object.
- with
NSObject
So, we think about it againid
What do types look like at the bottom?
And then we find the following code: typedef struct objc_object * ID;
So we can also conclude that underlying ID is essentially a pointer, and NSObject is essentially a structure. This also explains why creating objects with NSObject requires an *, but not an ID type.
3:Class
The underlying essential type is the structure pointer
Searching for Class, we find the following underlying code
typedef struct objc_class *Class;
struct objc_class {
Class _Nonnull isa __attribute__ ((deprecated));
} __attribute__ ((unavailable));
Copy the code
Note The underlying Class type is objC_class *, which is a structure pointer.
4:get
andset
The underlying implementation of a method.
First we find the implementation of the getter and setter parameters.
// Get
static NSString * _I_Person_Name(Person * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_Name)); }
// Set
static void _I_Person_setName_(Person * self, SEL _cmd, NSString *Name) { (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_Name)) = Name; }
Copy the code
We can note that:
- 1:
Get
withSet
The method sees two sets of parametersFFPserson * self
,SEL _cmd
This is the hidden parameter method that we normally createThe default carry
These two parameters, this is just asking what can we use in every methodself
The reason why - 2: in
Get
Method, we can see that if we want to read a member variable, we need to get the first address of the object, and then translate itOBJC_IVAR_
You can get the address of the corresponding member variable. Get the address and get the value.set
Same thing.
3: The relationship between the size of OC variable and its member variables.
First we create an object that inherits from NSObject and add a few member variables:
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@end
Copy the code
Then use the xcrun command to convert person. m to a C++ file: the above code can be expressed in C++ as:
struct Person_IMPL { struct NSObject_IMPL NSObject_IVARS; // isa [0,7] int _age; // [8, 9, 10, 11] NSString * _Nonnull _name; // (12, 13, 14, 15, [16, 17...23]) NSString * _Nonnull _nickName; // [24....32] long _height; // (33, 34, 35, [36...40])};Copy the code
The size of the structure Person_IMPL is 40+8 (16-byte alignment) = 48 bytes. Then we also verify the size of the OC object Person in the main function.
Person *person = [Person alloc];
person.name = @"Cooci";
person.nickName = @"KC";
NSLog(@"class_getInstanceSize([LGPerson class]): %lu", class_getInstanceSize([Person class]));
NSLog(@"malloc_size((__bridge const void *)(person)): %lu", malloc_size(( __bridge const void *)(person)));
Copy the code
The printed result is:
class_getInstanceSize([LGPerson class]): 40
malloc_size((__bridge const void *)(person)): 48
Copy the code
So it’s consistent with our analysis. From the above, we can draw two conclusions:
- 1.
Person
Object and thePerson_IMP
The size of the structure is consistent with the size of the occupied memory space. - 2. Within the object
Member variables
The size of the object determines how much memory the object actually occupies.
4: The relationship between object size and method
Let’s add some object methods and class methods to the Person object above:
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
- (void)test:(NSString *)str;
+ (NSString *)test1:(NSString *)str;
@end
Copy the code
And then I’m going to print it again
class_getInstanceSize([LGPerson class]): 40
malloc_size((__bridge const void *)(person)): 48
Copy the code
- Conclusion: Method add on Person
The size of the
andmemory
Size does not have any effect on the descriptionAdd the number of methods
Object to the OC objectThe size of the
No impact.
So why does the addition of methods not affect the size of the objectmain.cpp
The structure in.
- You can see that the compiled methods are commented out, the part that actually evaluates the size, or
Member variables
Section, so add to classInstantiation method
andClass method
Will not affectObject size
And object occupiedMemory size
.
Reference:
Juejin. Cn/post / 694962…
Copy the code