3030namespace firebase {
3131namespace util {
3232
33- // / Define a simple struct to wrap an Objective-C pointer.
33+ // / Define a class to wrap an Objective-C pointer.
3434// / Objective-C uses automatic reference counting, we can't just cast them to
35- // / void* to reference them from platform-independent data structures
36- // / (like firebase::App's data_ pointer). Instead, we wrap the pointer in this
37- // / struct, and point our void* at an instance of this struct.
38- // / It's awkward. A better solution would be welcome.
39- // /
40- // / Unfortunately, the _Nullable types can't be used with templates,
41- // / so we use a hokey macro instead.
42- // /
43- // / OBJ_C_PTR_WRAPPER(MyClass) unwraps to:
44- // / struct MyClassPointer {
45- // / MyClassPointer() : ptr(nil) {}
46- // / explicit MyClassPointer(MyClass *_Nullable ptr) : ptr(ptr) {}
47- // / ~MyClassPointer() { ptr = nil; }
48- // / MyClass *_Nullable ptr;
49- // / };
35+ // / void* or a forward declared C++ class to reference them from
36+ // platform-independent data structures (like firebase::App's data_ pointer).
37+ // / Instead, we wrap the pointer in this class.
5038// /
5139// / Usage:
5240// /
@@ -56,7 +44,11 @@ namespace util {
5644// / };
5745// /
5846// / // .cpp
59- // / OBJ_C_PTR_WRAPPER(MyObjCClass);
47+ // / typedef ObjCPointer<MyObjCClass> MyObjCClassPointer;
48+ // / // or OBJ_C_PTR_WRAPPER(MyObjCClass);
49+ // / // or OBJ_C_PTR_WRAPPER_NAMED(MyObjCClassPointer, MyObjCClass);
50+ // // OBJ_C_PTR_WRAPPER* define a class rather than a typedef which
51+ // // is useful when defining a forward declared class.
6052// /
6153// / void Init(MyPlatformIndependentClass* c, MyObjCClass* obj_c) {
6254// / c->platform_indep_ptr_ = new MyObjCClassPointer(obj_c);
@@ -68,15 +60,73 @@ namespace util {
6860// / }
6961// /
7062// / void DoSomething(MyPlatformIndependentClass* c) {
71- // / [static_cast<MyObjCClassPointer*>(c->platform_indep_ptr_)->ptr fn_name];
63+ // / [static_cast<MyObjCClassPointer*>(
64+ // / c->platform_indep_ptr_)->get() fn_name];
7265// / }
7366// /
74- #define OBJ_C_PTR_WRAPPER (type_name ) \
75- struct type_name##Pointer { \
76- type_name##Pointer () : ptr (nil ) {} \
77- explicit type_name##Pointer (type_name *_Nullable ptr) : ptr (ptr) {} \
78- ~type_name##Pointer () { ptr = nil ; } \
79- type_name *_Nullable ptr; \
67+ template <typename T>
68+ class ObjCPointer {
69+ public:
70+ // Construct with an empty class.
71+ ObjCPointer () : objc_object_ (nil ) {}
72+
73+ // Construct with a reference to an Obj-C object.
74+ explicit ObjCPointer (T *_Nullable objc_object ) : objc_object_ (objc_object ) {}
75+
76+ // Release the reference to the Obj-C object.
77+ ~ObjCPointer () { release (); }
78+
79+ // Determine whether the Obj-C object is valid.
80+ explicit operator bool () const { return get () != nil ; }
81+
82+ // Get the Obj-C object.
83+ T *_Nullable operator*() const { return get (); }
84+
85+ // Get the Obj-C object.
86+ T *_Nullable get () const { return objc_object_; }
87+
88+ // Release the reference to the Obj-C object.
89+ T *_Nullable release () {
90+ T *released = objc_object_;
91+ objc_object_ = nil ;
92+ return released;
93+ }
94+
95+ // Assign a new Obj-C object.
96+ void reset (T *_Nullable objc_object ) { objc_object_ = objc_object ; }
97+
98+ // Assign a new Obj-C object.
99+ ObjCPointer &operator=(T *_Nullable objc_object ) {
100+ reset (objc_object );
101+ return *this;
102+ }
103+
104+ // Get the Obj-C object from an ObjCPointer if the specified object is
105+ // non-null.
106+ static T *_Nullable SafeGet (const ObjCPointer *_Nullable reference) {
107+ return reference ? reference->get () : nil ;
108+ }
109+
110+ private:
111+ /* This should be private */
112+ T *_Nullable objc_object_;
113+ };
114+
115+ // Generate the class named class_name as an alias of ObjCPointer to contain
116+ // the Objective-C type objc_type_name.
117+ #define OBJ_C_PTR_WRAPPER_NAMED (class_name, objc_type_name ) \
118+ class class_name : public firebase::util::ObjCPointer<objc_type_name> { \
119+ public: \
120+ class_name () {} \
121+ explicit class_name ( \
122+ const firebase::util::ObjCPointer<objc_type_name>& obj) \
123+ : firebase::util::ObjCPointer<objc_type_name>(obj) {} \
124+ explicit class_name (objc_type_name *_Nullable objc_object ) \
125+ : firebase::util::ObjCPointer<objc_type_name>(objc_object ) {} \
126+ class_name &operator=(objc_type_name *_Nullable objc_object ) { \
127+ ObjCPointer<objc_type_name>::operator=(objc_object ); \
128+ return *this; \
129+ } \
80130 }
81131
82132// / Return an std::string created from an NSString pointer.
@@ -138,7 +188,7 @@ typedef BOOL (
138188// blacklist we keep).
139189void ForEachAppDelegateClass (void (^block)(Class ));
140190
141- // Convert a string array into an NSMutableArray.
191+ // Convert a string array into an NSMutableArray.
142192NSMutableArray *StringVectorToNSMutableArray (
143193 const std::vector<std::string> &vector);
144194
@@ -175,7 +225,8 @@ id VariantToId(const Variant &variant);
175225Variant IdToVariant (id value);
176226
177227// Converts an NSMutableDictionary mapping id-to-id to a map<Variant, Variant>.
178- void NSDictionaryToStdMap (NSDictionary *dictionary, std::map<Variant, Variant> *map);
228+ void NSDictionaryToStdMap (NSDictionary *dictionary, // NOLINT
229+ std::map<Variant, Variant> *map);
179230
180231// Runs a block on the main/UI thread immediately if the current thread is the
181232// main thread; otherwise, dispatches asynchronously to the main thread.
@@ -269,16 +320,21 @@ NS_ASSUME_NONNULL_END
269320// setting the existing method implementation on an app delegate. You can use
270321// this as the type encoding class for ReplaceOrAddMethod, if you are
271322// modifying methods on an app delegate class.
272- @interface FIRSAMAppDelegate : UIResponder <UIApplicationDelegate>
323+ @interface FIRSAMAppDelegate : UIResponder <UIApplicationDelegate>
273324@end
274325
275326#else
276327
277328// Define an opaque type for the Obj-C pointer wrapper struct when this header
278329// is included in plain C++ files.
279- #define OBJ_C_PTR_WRAPPER (type_name ) \
280- struct type_name##Pointer;
330+ #define OBJ_C_PTR_WRAPPER_NAMED (class_name, objc_type_name ) class class_name;
281331
282332#endif // __OBJC__
283333
334+ // Generate the class definition objc_type_name##Pointer which is a container
335+ // of the Objective-C type objc_type_name.
336+ // For more information, see ObjCPointer.
337+ #define OBJ_C_PTR_WRAPPER (objc_type_name ) \
338+ OBJ_C_PTR_WRAPPER_NAMED (objc_type_name##Pointer, objc_type_name)
339+
284340#endif // FIREBASE_APP_CLIENT_CPP_SRC_UTIL_IOS_H_
0 commit comments