]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/cocoa/ObjcRef.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/cocoa/ObjcRef.h
3 // Purpose: wxObjcAutoRef template class
4 // Author: David Elliott
8 // Copyright: (c) 2004 David Elliott <dfe@cox.net>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_COCOA_OBJCREF_H__
13 #define _WX_COCOA_OBJCREF_H__
15 // Reuse wxCFRef-related code (e.g. wxCFRetain/wxCFRelease)
16 #include "wx/osx/core/cfref.h"
18 // NOTE WELL: We can only know whether or not GC can be used when compiling Objective-C.
19 // Therefore we cannot implement these functions except when compiling Objective-C.
21 /*! @function wxGCSafeRetain
22 @templatefield Type (implicit) An Objective-C class type
23 @arg r Pointer to Objective-C object. May be null.
24 @abstract Retains the Objective-C object, even when using Apple's garbage collector
26 When Apple's garbage collector is enabled, the usual [obj retain] and [obj release] messages
27 are ignored. Instead the collector with help from compiler-generated write-barriers tracks
28 reachable objects. The write-barriers are generated when setting i-vars of C++ classes but
29 they are ignored by the garbage collector unless the C++ object is in GC-managed memory.
31 The simple solution is to use CFRetain on the Objective-C object which has been enhanced in
32 GC mode to forcibly retain the object. In Retain/Release (RR) mode the CFRetain function has
33 the same effect as [obj retain]. Note that GC vs. RR is selected at runtime.
35 Take care that wxGCSafeRetain must be balanced with wxGCSafeRelease and that conversely
36 wxGCSafeRelease must only be called on objects to balance wxGCSafeRetain. In particular when
37 receiving an Objective-C object from an alloc or copy method take care that you must retain
38 it with wxGCSafeRetain and balance the initial alloc with a standard release.
41 wxGCSafeRelease(m_obj); // release current object (if any)
42 NSObject *obj = [[NSObject alloc] init];
43 m_obj = wxGCSafeRetain(obj);
46 Alternatively (same effect, perhaps less clear):
47 wxGCSafeRelease(m_obj); // release current object (if any)
48 m_obj = wxGCSafeRetain([[NSObject alloc] init]);
49 [m_obj release]; // balance alloc
51 Consider the effect on the retain count from each statement (alloc, CFRetain, release)
52 In RR mode: retainCount = 1, +1, -1
53 In GC mode: strongRetainCount = 0, +1, -0
55 This is a template function to ensure it is used on raw pointers and never on pointer-holder
56 objects via implicit conversion operators.
59 inline Type
* wxGCSafeRetain(Type
*r
)
62 return static_cast<Type
*>(wxCFRetain(r
));
68 /*! @function wxGCSafeRelease
69 @templatefield Type (implicit) An Objective-C class type
70 @arg r Pointer to Objective-C object. May be null.
71 @abstract Balances wxGCSafeRetain. Particularly useful with the Apple Garbage Collector.
73 See the wxGCSafeRetain documentation for more details.
75 Example (from wxGCSafeRetain documentation):
76 wxGCSafeRelease(m_obj); // release current object (if any)
77 m_obj = wxGCSafeRetain([[NSObject alloc] init]);
78 [m_obj release]; // balance alloc
80 When viewed from the start, m_obj ought to start as nil. However, the second time through
81 the wxGCSafeRelease call becomes critical as it releases the retain from the first time
84 In the destructor for this C++ object with the m_obj i-var you ought to do the following:
85 wxGCSafeRelease(m_obj);
86 m_obj = nil; // Not strictly needed, but safer.
88 Under no circumstances should you balance an alloc or copy with a wxGCSafeRelease.
91 inline void wxGCSafeRelease(Type
*r
)
100 // NOTE: When not compiling Objective-C, declare these functions such that they can be
101 // used by other inline-implemented methods. Since those methods in turn will not actually
102 // be used from non-ObjC code the compiler ought not emit them. If it emits an out of
103 // line copy of those methods then presumably it will have also emitted at least one
104 // out of line copy of these functions from at least one Objective-C++ translation unit.
105 // That means the out of line implementation will be available at link time.
107 template <class Type
>
108 inline Type
* wxGCSafeRetain(Type
*r
);
110 template <class Type
>
111 inline void wxGCSafeRelease(Type
*r
);
113 #endif //def __OBJC__
116 wxObjcAutoRefFromAlloc: construct a reference to an object that was
117 [NSObject -alloc]'ed and thus does not need a retain
118 wxObjcAutoRef: construct a reference to an object that was
119 either autoreleased or is retained by something else.
124 // We must do any calls to Objective-C from an Objective-C++ source file
125 class wxObjcAutoRefBase
128 /*! @function ObjcRetain
129 @abstract Simply does [p retain].
131 static struct objc_object
* ObjcRetain(struct objc_object
*);
133 /*! @function ObjcRelease
134 @abstract Simply does [p release].
136 static void ObjcRelease(struct objc_object
*);
139 /*! @class wxObjcAutoRefFromAlloc
140 @templatefield T The type of _pointer_ (e.g. NSString*, NSRunLoop*)
141 @abstract Pointer-holder for Objective-C objects
143 When constructing this object from a raw pointer, the pointer is assumed to have
144 come from an alloc-style method. That is, once you construct this object from
145 the pointer you must not balance your alloc with a call to release.
147 This class has been carefully designed to work with both the traditional Retain/Release
148 and the new Garbage Collected modes. In RR-mode it will prevent the object from being
149 released by managing the reference count using the retain/release semantics. In GC-mode
150 it will use a method (currently CFRetain/CFRelease) to ensure the object will never be
151 finalized until this object is destroyed.
155 class wxObjcAutoRefFromAlloc
: wxObjcAutoRefBase
158 wxObjcAutoRefFromAlloc(T p
= 0)
160 // NOTE: this is from alloc. Do NOT retain
163 // GC: Object is strongly retained and prevented from being collected
164 // non-GC: Simply realizes it's an Objective-C object and calls [p retain]
166 // ObjcRelease (e.g. [p release])
167 // GC: Objective-C retain/release mean nothing in GC mode
168 // non-GC: This is a normal release call, balancing the retain
169 ObjcRelease(static_cast<T
>(p
));
170 // The overall result:
171 // GC: Object is strongly retained
172 // non-GC: Retain count is the same as it was (retain then release)
174 wxObjcAutoRefFromAlloc(const wxObjcAutoRefFromAlloc
& otherRef
)
175 : m_ptr(otherRef
.m_ptr
)
176 { wxGCSafeRetain(m_ptr
); }
177 ~wxObjcAutoRefFromAlloc()
178 { wxGCSafeRelease(m_ptr
); }
179 wxObjcAutoRefFromAlloc
& operator=(const wxObjcAutoRefFromAlloc
& otherRef
)
180 { wxGCSafeRetain(otherRef
.m_ptr
);
181 wxGCSafeRelease(m_ptr
);
182 m_ptr
= otherRef
.m_ptr
;
186 { return static_cast<T
>(m_ptr
); }
188 { return static_cast<T
>(m_ptr
); }
190 /*! @field m_ptr The pointer to the Objective-C object
192 The pointer to the Objective-C object is typed as void* to avoid compiler-generated write
193 barriers as would be used for implicitly __strong object pointers and to avoid the similar
194 read barriers as would be used for an explicitly __weak object pointer. The write barriers
195 are useless unless this object is located in GC-managed heap which is highly unlikely.
197 Since we guarantee strong reference via CFRetain/CFRelease the write-barriers are not needed
198 at all, even if this object does happen to be allocated in GC-managed heap.
206 A pointer holder that does retain its argument.
207 NOTE: It is suggest that you instead use wxObjcAutoRefFromAlloc<T> foo([aRawPointer retain])
210 class wxObjcAutoRef
: public wxObjcAutoRefFromAlloc
<T
>
213 /*! @method wxObjcAutoRef
215 Uses the underlying wxObjcAutoRefFromAlloc and simply does a typical [p retain] such that
216 in RR-mode the object is in effectively the same retain-count state as it would have been
217 coming straight from an alloc method.
219 wxObjcAutoRef(T p
= 0)
220 : wxObjcAutoRefFromAlloc
<T
>(p
)
221 { // NOTE: ObjcRetain is correct because in GC-mode it balances ObjcRelease in our superclass constructor
222 // In RR mode it does retain and the superclass does retain/release thus resulting in an overall retain.
223 ObjcRetain(static_cast<T
>(wxObjcAutoRefFromAlloc
<T
>::m_ptr
));
226 wxObjcAutoRef(const wxObjcAutoRef
& otherRef
)
227 : wxObjcAutoRefFromAlloc
<T
>(otherRef
)
229 wxObjcAutoRef(const wxObjcAutoRefFromAlloc
<T
>& otherRef
)
230 : wxObjcAutoRefFromAlloc
<T
>(otherRef
)
232 wxObjcAutoRef
& operator=(const wxObjcAutoRef
& otherRef
)
233 { return wxObjcAutoRefFromAlloc
<T
>::operator=(otherRef
); }
236 #endif //ndef _WX_COCOA_OBJCREF_H__