1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_SCOPED_NSOBJECT_H_ 6 #define BASE_SCOPED_NSOBJECT_H_ 7 8 #import <Foundation/Foundation.h> 9 #include "base/basictypes.h" 10 11 // scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership 12 // of an NSObject subclass object. Style deviations here are solely for 13 // compatibility with scoped_ptr<>'s interface, with which everyone is already 14 // familiar. 15 // 16 // When scoped_nsobject<> takes ownership of an object (in the constructor or 17 // in reset()), it takes over the caller's existing ownership claim. The 18 // caller must own the object it gives to scoped_nsobject<>, and relinquishes 19 // an ownership claim to that object. scoped_nsobject<> does not call 20 // -retain. 21 // 22 // scoped_nsobject<> is not to be used for NSAutoreleasePools. For 23 // NSAutoreleasePools use ScopedNSAutoreleasePool from 24 // scoped_nsautorelease_pool.h instead. 25 // We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile 26 // time with a template specialization (see below). 27 template<typename NST> 28 class scoped_nsobject { 29 public: 30 typedef NST* element_type; 31 32 explicit scoped_nsobject(NST* object = nil) object_(object)33 : object_(object) { 34 } 35 ~scoped_nsobject()36 ~scoped_nsobject() { 37 [object_ release]; 38 } 39 40 void reset(NST* object = nil) { 41 // We intentionally do not check that object != object_ as the caller must 42 // already have an ownership claim over whatever it gives to scoped_nsobject 43 // and scoped_cftyperef, whether it's in the constructor or in a call to 44 // reset(). In either case, it relinquishes that claim and the scoper 45 // assumes it. 46 [object_ release]; 47 object_ = object; 48 } 49 50 bool operator==(NST* that) const { 51 return object_ == that; 52 } 53 54 bool operator!=(NST* that) const { 55 return object_ != that; 56 } 57 58 operator NST*() const { 59 return object_; 60 } 61 get()62 NST* get() const { 63 return object_; 64 } 65 swap(scoped_nsobject & that)66 void swap(scoped_nsobject& that) { 67 NST* temp = that.object_; 68 that.object_ = object_; 69 object_ = temp; 70 } 71 72 // scoped_nsobject<>::release() is like scoped_ptr<>::release. It is NOT 73 // a wrapper for [object_ release]. To force a scoped_nsobject<> object to 74 // call [object_ release], use scoped_nsobject<>::reset(). release()75 NST* release() { 76 NST* temp = object_; 77 object_ = nil; 78 return temp; 79 } 80 81 private: 82 NST* object_; 83 84 DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); 85 }; 86 87 // Specialization to make scoped_nsobject<id> work. 88 template<> 89 class scoped_nsobject<id> { 90 public: 91 typedef id element_type; 92 93 explicit scoped_nsobject(id object = nil) object_(object)94 : object_(object) { 95 } 96 ~scoped_nsobject()97 ~scoped_nsobject() { 98 [object_ release]; 99 } 100 101 void reset(id object = nil) { 102 // We intentionally do not check that object != object_ as the caller must 103 // already have an ownership claim over whatever it gives to scoped_nsobject 104 // and scoped_cftyperef, whether it's in the constructor or in a call to 105 // reset(). In either case, it relinquishes that claim and the scoper 106 // assumes it. 107 [object_ release]; 108 object_ = object; 109 } 110 111 bool operator==(id that) const { 112 return object_ == that; 113 } 114 115 bool operator!=(id that) const { 116 return object_ != that; 117 } 118 id()119 operator id() const { 120 return object_; 121 } 122 get()123 id get() const { 124 return object_; 125 } 126 swap(scoped_nsobject & that)127 void swap(scoped_nsobject& that) { 128 id temp = that.object_; 129 that.object_ = object_; 130 object_ = temp; 131 } 132 133 // scoped_nsobject<>::release() is like scoped_ptr<>::release. It is NOT 134 // a wrapper for [object_ release]. To force a scoped_nsobject<> object to 135 // call [object_ release], use scoped_nsobject<>::reset(). release()136 id release() { 137 id temp = object_; 138 object_ = nil; 139 return temp; 140 } 141 142 private: 143 id object_; 144 145 DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); 146 }; 147 148 // Do not use scoped_nsobject for NSAutoreleasePools, use 149 // ScopedNSAutoreleasePool instead. This is a compile time check. See details 150 // at top of header. 151 template<> 152 class scoped_nsobject<NSAutoreleasePool> { 153 private: 154 explicit scoped_nsobject(NSAutoreleasePool* object = nil); 155 DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); 156 }; 157 158 #endif // BASE_SCOPED_NSOBJECT_H_ 159