This exploration stems from a question asked by a friend. When we define an instance variable of a class, we can specify its modifier:
This allows ivar (instance variable) to be correctly reference counted under ARC just like properties. So the question is, if this class is dynamically generated:
How do you add property modifiers to ivar like above? After some investigation, I found that the modification information of ivar is stored in the Ivar Layout of Class:
ivarLayout and weakIvarLayout respectively record which ivars are strong or weak. What is not recorded are the basic types and __unsafe_unretained object types. These two values can be accessed through several APIs provided by the runtime:
But we are unlikely to use these APIs. The value of IvarLayout is determined by the runtime, so there is no need to care about its existence. However, in order to solve the above problems, we tried to crack the encoding method of IvarLayout. For example, if the class is defined as:
The value of ivarLayout storing strong ivar is 0x012000 The value of weakIvarLayout that stores weak ivar is 0x1200 A uint8_t is two digits in hexadecimal, so the encoded value is a pair of two digits. Take the above ivarLayout as an example: The first two digits 01 indicate that there are 0 non-strong objects and 1 strong object. The next two digits 20 indicate that there are 2 non-strong objects and 0 strong objects. ***The two 00s are the end character, just like the \0 in cstring Similarly, the weakIvarLayout above: The first two digits 12 indicate that there is 1 non-weak object and the next 2 consecutive weak objects. 00 End character In this way, two layout code values can be used to check whether an ivar is strong or weak. If neither is found, it means that the object is unsafe_unretained. As an exercise, if the class is defined as:
The value of ivarLayout storing strong ivar is 0x012100 The value of weakIvarLayout that stores weak ivar is 0x01211000
I thought I had solved this problem, but the runtime continued to slap me in the face, and the strong and weak memory management did not take effect. I continued to study and found that there is a flag in the class flags to record whether the class is ARC. When the class is compiled normally and marked with the -fobjc-arc flag, this flag is 1, but the dynamically created class does not set it. So I can only continue to use black magic to set this flag at runtime. I will not go into details about the exploration process. The implementation is as follows:
After putting this fixup in objc_registerClassPair(class);, the dynamic class can finally operate ivar like the statically compiled class. You can test it:
Done. |
<<: 5 Best AngularJS Program Building Frameworks
>>: 4 memory usage issues game developers need to pay attention to
The ranking factors for link popularity of a spec...
(Image source: BBC) Have you ever seen people lik...
Today, I suddenly felt like talking to you about ...
Recently, the advanced on-demand broadcast of &qu...
Before we knew it, someone posted a message on We...
1 The purpose of advertising is either branding o...
For the person in charge of bidding SEM, the most...
For many people in the southern region, eating Qi...
About seven or eight years ago, a friend who ran ...
Author: Zhao Zhigang, Chief Pharmacist, Beijing T...
Is Leonardo da Vinci familiar to everyone? You wi...
What is the source of happiness? It must be carbo...
Introduction: In the growth analysis of a product...
According to Nikkei, Pakistan's auto market i...
This week, we specially invited Yi Yi, a former s...