• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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