30
30
namespace firebase {
31
31
namespace util {
32
32
33
- // / Define a simple struct to wrap an Objective-C pointer.
33
+ // / Define a class to wrap an Objective-C pointer.
34
34
// / 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.
50
38
// /
51
39
// / Usage:
52
40
// /
@@ -56,7 +44,11 @@ namespace util {
56
44
// / };
57
45
// /
58
46
// / // .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.
60
52
// /
61
53
// / void Init(MyPlatformIndependentClass* c, MyObjCClass* obj_c) {
62
54
// / c->platform_indep_ptr_ = new MyObjCClassPointer(obj_c);
@@ -68,15 +60,73 @@ namespace util {
68
60
// / }
69
61
// /
70
62
// / 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];
72
65
// / }
73
66
// /
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
+ } \
80
130
}
81
131
82
132
// / Return an std::string created from an NSString pointer.
@@ -138,7 +188,7 @@ typedef BOOL (
138
188
// blacklist we keep).
139
189
void ForEachAppDelegateClass (void (^block)(Class ));
140
190
141
- // Convert a string array into an NSMutableArray.
191
+ // Convert a string array into an NSMutableArray.
142
192
NSMutableArray *StringVectorToNSMutableArray (
143
193
const std::vector<std::string> &vector);
144
194
@@ -175,7 +225,8 @@ id VariantToId(const Variant &variant);
175
225
Variant IdToVariant (id value);
176
226
177
227
// 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);
179
230
180
231
// Runs a block on the main/UI thread immediately if the current thread is the
181
232
// main thread; otherwise, dispatches asynchronously to the main thread.
@@ -269,16 +320,21 @@ NS_ASSUME_NONNULL_END
269
320
// setting the existing method implementation on an app delegate. You can use
270
321
// this as the type encoding class for ReplaceOrAddMethod, if you are
271
322
// modifying methods on an app delegate class.
272
- @interface FIRSAMAppDelegate : UIResponder <UIApplicationDelegate>
323
+ @interface FIRSAMAppDelegate : UIResponder <UIApplicationDelegate>
273
324
@end
274
325
275
326
#else
276
327
277
328
// Define an opaque type for the Obj-C pointer wrapper struct when this header
278
329
// 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;
281
331
282
332
#endif // __OBJC__
283
333
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
+
284
340
#endif // FIREBASE_APP_CLIENT_CPP_SRC_UTIL_IOS_H_
0 commit comments