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
SEO is an inductive science, which cannot be expl...
In the season of rebirth, I heard that everyone w...
Recently, I often hear my colleague (finally onli...
The International Federation of Red Cross and Red...
Now that you have the APP, the next step is to op...
"The times define advertising, advertising a...
Many netizens have been asking about cooking oil,...
gossip Every year when the seasons change, many e...
Training course video content introduction: The c...
Information flow advertising style - live broadca...
In this fast-paced, information-based society, yo...
What is the price to join the Xiantao Check-in Mi...
[[124824]] 2014 is coming to an end, and it is cl...
There are some things that you cannot think about...
[[258480]] "Ding", "Payment succes...