2014-10-07 51 views
0

我想將ObjC通知處理程序公開給我的C++客戶端代碼。 我正在這樣做。通用Objective-to-C++翻譯策略

  1. 我包裹一個ObjC對象(稱之爲X)C++對象的內部。
  2. X觀察通知和註冊回調(稱之爲˚F)。
  3. ˚F轉換的ObjC結構從通知到他們的C++同行,調用用戶註冊全球C++回調函數(稱之爲FF)。翻譯後的C++結構成爲輸入參數FF

現在的問題是參數的原始ObjC結構很複雜,包含需要翻譯的多個ObjC對象層。

在我的身邊,包裝觀察者˚F需要做什麼特別的,只是調用客戶端的FF

這個時候我的翻譯更合適的策略是什麼?

我應該:

  1. 翻譯那些結構到所有成員的底部水平,使我有同樣的C++結構作爲參數來使用,或者,
  2. 創建一個C++類來包裝這些參數放入一個對象中,並將類接口公開給用戶,以便他們可以在C++實現中使用這些C++封裝的參數,或者放棄包裝思想並要求用戶在ObjC中編寫代碼並註冊他們自己的觀察者函數直?

我的目標用戶是iOS開發人員,他們可能也可能不是Android開發人員。

回答

1

您可以在.mm實現文件中混合使用C++和objective-C++。這意味着您可以將C++ lambda(或塊)提供給引用您的C++所有者的objective-C++類。

是這樣的:

implementation.mm:

@interface Shim : NSObject 
{ 
    std::function<void>() _notify; 
} 
@end 

@implementation Shim 
- void register_cpp(std::function<void>() f) 
{ 
    _notify = std::move(f); 
} 

- (void) my_handler() 
{ 
    if(_notify) 
    _notify(); 
} 
@end 

struct cpp_class::impl { 
    impl() 
    : _shim([Shim alloc[init]]) 
    { 
    _shim.register_cpp(std::bind(&impl::callback, this)); 
    } 

private: 
    void callback() { 
    // do callback here; 
    } 
    Shim* _shim; 
}; 

cpp_class::cpp_class() 
: _impl(new impl) 
{ 
} 

cpp_class::~cpp_class() 
{ 
    delete _impl; 
} 

頭。H:

struct cpp_class{ 
    cpp_class(); 
    ~cpp_class(); 

private: 
    struct impl; 
    impl* _impl; 
}; 

在現實中你要小心,以確保對象做回調時仍然存在(主張的weak_ptr ::鎖(),enable_shared_from_this等),因爲Objective-C的喜歡把回調到一個線程的運行循環(基本上是一個隊列),這意味着你的C++對象可以在回調到達之前消失 - 但是這個代碼應該給你正確的想法。