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
Recently, many places in China are experiencing a...
Since mid-May, JD.com has launched the slogan of ...
According to the latest research report released b...
In 1937, Qian Sanqiang went to the University of ...
recently #Girl complains about the anti-human des...
A few days ago, Yidao released a set of posters w...
With the end of winter, many people are planning ...
When you are engaged in marketing- related work, ...
The beautiful bony tongue fish in the picture has...
In 1971, paleontologists discovered two extremely...
Life experience tells us that it is important to ...
Self-media is very popular now, and many people w...
While iPhone 6 and iPhone 6S have become a hot to...
If you want to increase brand exposure, tap into ...
Event operations usually involve attracting traff...