Objective-C++之内存管理

Objective-C++内存管理


在项目开发时,有时会使用C++来进行混合开发,因为C++有很好的跨平台及性能优势。我们可以将C++对象作为Objective-C的属性或者反过来Objective-C作为C++对象的成员,当我们需要在App中使用C++库时,会很有用。

当我们的文件同时使用了Objective-CC++时,需要告知编译器来进行处理,方法为将该文件的后缀从.m改为.mm

如下示例展示了Objective-CC++互相作为成员变量来关联:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Forward declare so that everything works below
@class ObjcClass;
class CppClass;

// C++ class with an Objective-C member variable
class CppClass {
public:
ObjcClass *objcClass;
};

// Objective-C class with a C++ object as a property
@interface ObjcClass : NSObject
@property (nonatomic, assign) std::shared_ptr<CppClass> cppClass;
@end

@implementation ObjcClass
@end

// Using the two classes above
std::shared_ptr<CppClass> cppClass(new CppClass());
ObjcClass *objcClass = [[ObjcClass alloc] init];

cppClass->objcClass = objcClass;
objcClass.cppClass = cppClass;

如上,我们注意到,属性声明成了assign,而不是我们通常使用的strongweak,原因就是对于非Objective-C类型对象来说是没有意义的,编译器无法retainrelease一个C++对象,因为它不是一个Objective-C对象类型。

尽管声明属性为assign,但是内存管理依然能正确处理;不过这里要注意的是,如果我们使用原始指针来保存,这时候就需要自己进行内存管理了。

Objective-C对象实例总是在堆上分配,但是C++实例可以在栈或堆上。所以我们把分配在栈上的C++实例赋值给Objective-C的成员变量时,就有点奇怪,不过不用担心,它其实会放到堆上,因为整个Objective-C对象都是在堆上的。编译器实现这个转化的方式为:在allocdealloc方法中构建和析构C++对象,分别调用object_cxxConstructobject_cxxDestruct方法,来处理C++对象。

所以,对于所有基于栈的C++对象,不需要担心内存的问题,编译器自动接管。但是再强调一下,基于堆的C++对象,需要手动管理内存,如在deallocdelete``C++对象。

Game Over!!!