1. Review
In the previous blog, OC bottom for a series of exploration analysis, I believe that small partners have learned a certain knowledge, but the bottom source analysis is boring, so this time on some interview questions for analysis.
1.1 supplement
In the previous blog, we mainly talked about class extension and class association object. We haven’t talked about removing association yet, so here is a little bit to add.
- Removing associated Objects
objc_removeAssociatedObjects
void objc_removeAssociatedObjects(id object)
{
if (object && object->hasAssociatedObjects()) {
_object_remove_assocations(object, /*deallocating*/false); }}Copy the code
_object_remove_assocations
void
_object_remove_assocations(id object, bool deallocating)
{
ObjectAssociationMap refs{};
{
AssociationsManager manager;
AssociationsHashMap &associations(manager.get());
AssociationsHashMap::iterator i = associations.find((objc_object *)object);
if(i ! = associations.end()) { refs.swap(i->second);// If we are not deallocating, then SYSTEM_OBJECT associations are preserved.
bool didReInsert = false;
if(! deallocating) {for (auto &ref: refs) {
if (ref.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
i->second.insert(ref);
didReInsert = true; }}}if (!didReInsert)
associations.erase(i);
}
}
// Associations to be released after the normal ones.
SmallVector<ObjcAssociation *, 4> laterRefs;
// release everything (outside of the lock).
for (auto &i: refs) {
if (i.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
// If we are not deallocating, then RELEASE_LATER associations don't get released.
if (deallocating)
laterRefs.append(&i.second);
} else{ i.second.releaseHeldValue(); }}for(auto *later: laterRefs) { later->releaseHeldValue(); }}Copy the code
Above 👆 this is the code to remove the associated object, here we will not analyze the source code, let’s see where to call
During the object lifecycle, dealloc
dealloc
// Replaced by NSZombies
- (void)dealloc {
_objc_rootDealloc(self);
}
Copy the code
_objc_rootDealloc
void
_objc_rootDealloc(id obj)
{
ASSERT(obj);
obj->rootDealloc();
}
Copy the code
When the object is released, it goes to rootDealloc
rootDealloc
inline void
objc_object::rootDealloc()
{
if (isTaggedPointer()) return; // fixme necessary?
if(fastpath(isa.nonpointer && ! isa.weakly_referenced && ! isa.has_assoc &&#if ISA_HAS_CXX_DTOR_BIT! isa.has_cxx_dtor &&#else! isa.getClass(false)->hasCxxDtor() &&
#endif! isa.has_sidetable_rc)) { assert(! sidetable_present()); free(this);
}
else {
object_dispose((id)this); }}Copy the code
Isa. nonpointer, isa.weakly_referenced, isa.has_assoc, etc., will be identified, and object_Dispose if any.
object_dispose
id
object_dispose(id obj)
{
if(! obj)return nil;
objc_destructInstance(obj);
free(obj);
return nil;
}
Copy the code
Enter objc_destructInstance to destroy the instance
objc_destructInstance
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = obj->hasAssociatedObjects();
// This order is important.
if (cxx) object_cxxDestruct(obj);
if (assoc) _object_remove_assocations(obj, /*deallocating*/true);
obj->clearDeallocating();
}
return obj;
}
Copy the code
We’re going to use the _object_remove_assocations method to remove the associated objects.
Therefore, the associated objects do not need to be removed manually, they will be automatically released when dealloc
2. IOS Interview Question Analysis
2.1 load and c++ constructor call sequence
load
Is in thedyld
The callbackload_images
The callback is called in_objc_init
In the process of registration.C++
Constructor for the sameimage
It is inload
After the callbackdyld
The call. (Not absolutely)image
Internally, all classes are loaded first+ load
, and then load the + for the classificationload
, and finally loadC++
Global constructor. (classload
– > classificationload
->C++
Constructor).+load
isobjc
Is called,C++
The global constructor is indyld
Is called in. (image
The internal order defaults to byCompile Sources
Of course, for library dependenciesimage
, the dependency library +load is called first).Dyld
Initialize theimage
Is in accordance with theLink Binary With Libraries
Initializing the main program sequentially, starting with subscript 1 and finally initializing the main program (subscript 0).- Of course for the same
image
In terms ofC++
The constructor in theload
Later calls are not absolute. Such asobjc
System library, in progressdyld
That calls its own library before registering the callbackC++
Constructor (self-opening).
2.2 What is Runtime?
runtime
Is made up ofC
和C++
/assembly
A set of implementationsAPI
forOC
The language adds object-oriented, runtime functionality.- It’s an operating mechanism, not an underlying mechanism.
dyld
,assembly
,objc
,macho
It’s the bottom. - Everyday written
OC
The code, as the program runs, actually ends up being converted toRuntime
theC
Language code,Runtime
是Objective-C
Behind the scenes.
2.3 Initialize Call sequence
-
Initialize is called when the message is first sent.
-
Load is called at load_images, which precedes the initialize call (which is called during a slow lookupimporforward lookup).
-
Load > C++ constructor > initialize.
2.4 Call order of classification methods with the same name
There are two cases of the call order of the same classification method:
- In the case where the class is merged into the main class, that is, there is only one/or no load method, the entire list of methods is a one-dimensional array (regardless of other dynamically added methods). Finally, the compiled classification method with the same name will be placed before the main class and other categories. In the binary search of methods, the search will start from the middle, and when the corresponding method SEL is found, the search will continue until the first method with the same name is found.
- In the case that the classes are not merged into the main class, multiple load methods, the whole list of methods is a two-dimensional array, and the classes that are loaded after compilation are at the front of the array, and when you look for the methods, you look at them from the front.
- That is, the method with the same name will eventually find the method with the same name of the class that has been compiled and loaded, but the process is different.
The analysis blog also covers some loading of categories and load methods.
2.5 What are the differences between classification and extension?
First let’s look at what is classification and extension
category
: Category/classification
- Used specifically to add new methods to a class
- You cannot add a member attribute to a class. If you add a member variable, you cannot fetch it
Pay attention to
: Yes, actuallyruntime
Add attributes to the category- Classification using
@property
If you define variables, only variables will be generatedgetter,setter
Method declaration, cannot generate method implementation and underlineMember variables
.
extension
: class extensions
- It’s kind of a special category, it’s also called
Anonymous classification
- You can add to a class
Member attribute
, but isPrivate variables
- You can add methods to classes, again
Private methods
We are already familiar with the categories, so there is no need to go into them too much here. Here is the extension
extension
Class extension, we usually use is very much, as follows
what ? What, is this an extension? Use every day unexpectedly do not know!
Yes, this is the extension, usually used a lot, but a lot of people don’t know.
Note: The class extension should come after the declaration and before the implementation, otherwise an error will be reported.
More to come
🌹 just like it 👍🌹
🌹 feel have harvest, can come a wave, collect + concern, comment + forward, lest you can’t find me next 😁🌹
🌹 welcome everyone to leave a message to exchange, criticize and correct, learn from each other 😁, improve self 🌹