Objective-C можно до некоторой степени смешивать с c ++, и можно вызывать друг друга. Но объекты Objective-C по-прежнему управляются более или менее вручную, а идиома RAII полностью отсутствует в языке. Интересно, можно ли управлять сроками жизни объектов Objective-C с помощью интеллектуальных указателей C ++. Особенно теперь, когда в стандарт C ++ 11 добавлены функции boost scoped_ptr
и shared_ptr
.
Управление объектами Objective-C с помощью c ++ std :: unique_ptr ‹› или std :: shared_ptr ‹›
Ответы (1)
Но объекты Objective-C по-прежнему управляются более или менее вручную, а идиома RAII полностью отсутствует в языке.
Думаю, это так или иначе ответит на ваш вопрос. Поскольку объекты Objective-C подсчитываются по ссылкам, они уже выполняют цель, для которой были созданы интеллектуальные указатели: отделить или связать время жизни объекта с областью действия метода, в котором он содержится. scoped_ptr
s можно воссоздать с помощью пулов автозапуска, а shared_ptr
s - с помощью _3 _-_ 4_ или strong
ссылок.
Но говорить «нет» - это скучно. Если вы действительно хотите смешать Objective-C и C ++ вот так, нам нужно сначала ослабить определение «объекта Objective-C». Среда выполнения распознает все, что isa
является своим первым членом в качестве объекта, и мы можем воспользоваться этим и написать простой класс C ++ с соответствующим интерфейсом объекта, чтобы можно было отправлять сообщения:
@interface CFIObject : NSObject
- (void)doSomething;
@end
struct CFIObject_cxx {
Class isa;
public:
CFIObject_cxx() : isa([CFIObject class]) {}
~CFIObject_cxx() { printf("I'm dying!"); }
};
@implementation CFIObject
- (void)doSomething {
NSLog("I did something.");
}
@end
Теперь мы можем создать экземпляр нашего объекта C ++ и обернуть его интеллектуальным указателем, который я намеренно разделю на два метода, чтобы проиллюстрировать время жизни объекта:
void func() {
// Instantiate a smart pointer with our fake object.
std::unique_ptr<CFIObject_cxx> cppObj (new CFIObject_cxx());
id obj = (__bridge id)(cppObj.get());
// The runtime thinks we're an object.
[obj doSomething];
// aaaand, it's out of scope.
}
int main(int argc, const char **argv) {
func();
return 0;
}
Как и следовало ожидать, это печатает:
2013-12-22 17:23:22.681 Test[77528:303] I did something
I'm dying!
к консоли.
В случае необходимости деструктор может быть оборудован для вызова -dealloc
для имитации правильного разрушения объекта, но я надеюсь, вы видите, что все это совершенно не нужно, особенно с учетом того, что ARC становится умнее с каждым выпуском CLANG.