writing
When Does an Objective-C Object Held by a C++ Class Get dealloc'd?C++ 类中持有的 Objective-C 对象何时 dealloc
· Performance & internals
Translated from Chinese — .
On this page
When using Objective-C++, you can store Objective-C objects in a C++ struct or class.
For example:
struct CppStruct {
MyObject *obj;
};
So I suddenly wondered: if CppStruct is destructed, will MyObject be dealloc’d? No need to overthink it — of course it will. But how is that achieved?
Let’s write some code to verify it:
@interface MyObject : NSObject
@end
@implementation MyObject
- (instancetype)init {
self = [super init];
if (self) {
NSLog(@"MyObject init");
}
return self;
}
- (void)dealloc {
NSLog(@"MyObject dealloc");
}
@end
struct CppStruct {
MyObject *obj;
CppStruct() {
NSLog(@"CppStruct constructor");
}
~CppStruct() {
NSLog(@"CppStruct destructor");
}
};
CppStruct * CreateStruct() {
CppStruct * s = new CppStruct();
s->obj = [[MyObject alloc] init];
return s;
}
void FreeStruct(CppStruct *s) {
delete s;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
CppStruct *s = CreateStruct();
FreeStruct(s);
}
return 0;
}
It produces the following output:

As you can see, MyObject indeed got dealloc’d.
So, let’s set a breakpoint on dealloc and see how it gets called.

In the image above there are two ~CppStruct(), one of which calls objc_storeStrong, and objc_storeStrong in turn triggers MyObject’s dealloc.

From the image above, it must be the compiler that generated the code calling objc_storeStrong.

Looking at the Disassembly, it indeed generated the objc_storeStrong call code.

Solid confirmation.
As for how LLVM generates this logic — I won’t dig into that here.
References
The debugging above used a compilable objc runtime. There are many on GitHub; you can just search for the corresponding objc version like this:
https://github.com/search?q=objc+779.1 https://github.com/LGCooci/objc4_debug
Summary
From now on you can boldly use C++ structs to store Objective-C objects.
Pretty interesting :)
在使用Objective C++时,可以用C++的struct或者class存储Objective C对象。
例如:
struct CppStruct {
MyObject *obj;
};
那么突然想,如果CppStruct析构了,MyObject会dealloc吗?不用多想,肯定也会。但如何做到的呢?
写段代码验证下,
@interface MyObject : NSObject
@end
@implementation MyObject
- (instancetype)init {
self = [super init];
if (self) {
NSLog(@"MyObject init");
}
return self;
}
- (void)dealloc {
NSLog(@"MyObject dealloc");
}
@end
struct CppStruct {
MyObject *obj;
CppStruct() {
NSLog(@"CppStruct constructor");
}
~CppStruct() {
NSLog(@"CppStruct destructor");
}
};
CppStruct * CreateStruct() {
CppStruct * s = new CppStruct();
s->obj = [[MyObject alloc] init];
return s;
}
void FreeStruct(CppStruct *s) {
delete s;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
CppStruct *s = CreateStruct();
FreeStruct(s);
}
return 0;
}
如下输出

可知,MyObject确实dealloc了。
那么,断点到dealloc,看看怎么调用到的。

看到上图有两个 ~CppStruct(),其中一个调用了 objc_storeStrong,objc_storeStrong 进一步触发了MyObject的dealloc。

从上图可知,一定是编译器生成了objc_storeStrong调用的代码。

看下Disassembly,确实生成了objc_storeStrong调用代码。

进一步实锤。
LLVM 怎么去生成的这个逻辑,就不去翻了哈。
参考
上面调试中用了可编译的objc runtime,GitHub上有很多,可以如下搜索对应objc版本即可:
https://github.com/search?q=objc+779.1 https://github.com/LGCooci/objc4_debug
总结
以后可以大胆的用C++ struct 存储Objective C对象了。
很有趣 :)