Я создаю приложение в C++, используя cocos2d-x. Для некоторой работы по интеграции мне нужно вызвать код Objective C с асинхронным ответом, реализованным путем вызова метода обратного вызова C++ из Objective C.
TL;DR;как я должен освободить мост C++ до Objective C всякий раз, когда заканчивается обратный вызов?Должен ли я реализовать мост как статическую переменную-член?
Для основной части C++ для Objective C я следовал за руководством Jesús Bosch, поскольку для вызова C++ из Objective C я следил за сообщением своих коллег.
В принципе, у меня закончилась следующая настройка.
Во-первых, у нас есть MyApp.h
class MyApp
{
public:
static void buttonChosen(int index);
void callObjC();
// ...
}
и MyApp.cpp
, который отвечает за MyApp.cpp
кода Objective C.
void MyApp::buttonChosen(int index)
{
log("Button choosen: %d", index);
}
void MyApp::callObjC()
{
iOSBridge::iOSHelper* bridge = new iOSBridge::iOSHelper();
bridge->ShowAlert(buttonChosen);
// delete bridge;
}
Тогда у меня есть мост, iOSBridge.h
namespace iOSBridge{
class iOSHelper {
public:
void(*callback)(int index);
iOSHelper() { }
void ShowAlert(void(*callback)(int));
};
}
и его реализация iOSHelper.cpp
#include "iOSHelper.h"
#import "IsolatedAlert.h"
namespace iOSBridge{
void iOSHelper::ShowAlert(void(*callback)(int index))
{
this->callback = callback;
IsolatedAlert* instance = [IsolatedAlert new];
[instance showAlert: this];
}
}
Наконец, есть IsolatedAlert.h
#import <UIKit/UIKit.h>
#import "iOSHelper.h"
typedef struct iOSBridge::iOSHelper iOsType;
@interface IsolatedAlert : UIViewController
-(void)showAlert:(iOsType*)callback;
@end
и его реализация IsolatedAlert.mm
#import "IsolatedAlert.h"
iOsType* staticPointer;
@implementation IsolatedAlert
-(void)showAlert:(iOsType*)callback
{
staticPointer = callback;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title?"
message:@"Message?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
[alert show];
[alert release];
}
-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
staticPointer->callback(buttonIndex);
}
@end
Теперь, мой вопрос заключается в следующем: как мне выпустить iOSBridge::iOSHelper* bridge
каждый раз, когда buttonChosen()
? Является ли он реализацией как статический член ok, если я обещаю, что не будет экземпляра экземпляра MyApp
созданного в любой момент? Благодарю!
Обычным способом C++ для выпуска экземпляра, созданного с помощью new
является использование ключевого слова delete
:
void MyApp::buttonChosen(int index)
{
log("Button choosen: %d", index);
delete bridge;
bridge = NULL;
}
Хорошей практикой является NULL
указатель после удаления, чтобы гарантировать, что приложение ведет себя согласованным образом (сбой) в случае, если объект используется после delete
. Если вы этого не сделаете, ваше приложение может работать некоторое время, производить неправильные результаты, показывать странное поведение или случайный случай аварии или все вышеупомянутое.
Ах, и, конечно же, вы должны сделать указатель моста переменной-членом вашего класса App.
#include "iOSHelper.h"
class MyApp
{
public:
static void buttonChosen(int index);
void callObjC();
// ...
protected:
iOSBridge::iOSHelper* bridge;
}
Вы также должны подумать о том, чтобы сделать существующие методы protected
или private
потому что buttonChosen, вероятно, не является методом, который вы хотите вызвать из-за пределов экземпляра MyApp.