Flutter Engine
The Flutter Engine
scoped_nsobject.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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 ACCESSIBILITY_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
6#define ACCESSIBILITY_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
7
8// Include NSObject.h directly because Foundation.h pulls in many dependencies.
9// (Approx 100k lines of code versus 1.5k for NSObject.h). scoped_nsobject gets
10// singled out because it is most typically included from other header files.
11#import <Foundation/NSObject.h>
12
14#include "base/macros.h"
15
16@class NSAutoreleasePool;
17
18namespace base {
19
20// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
21// of an NSObject subclass object. Style deviations here are solely for
22// compatibility with scoped_ptr<>'s interface, with which everyone is already
23// familiar.
24//
25// scoped_nsobject<> takes ownership of an object (in the constructor or in
26// reset()) by taking over the caller's existing ownership claim. The caller
27// must own the object it gives to scoped_nsobject<>, and relinquishes an
28// ownership claim to that object. scoped_nsobject<> does not call -retain,
29// callers have to call this manually if appropriate.
30//
31// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
32// with protocols.
33//
34// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
35// NSAutoreleasePools use ScopedNSAutoreleasePool from
36// scoped_nsautorelease_pool.h instead.
37// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
38// time with a template specialization (see below).
39
40template <typename NST>
42 public:
43 explicit scoped_nsprotocol(NST object = nil) : object_(object) {}
44
45 scoped_nsprotocol(const scoped_nsprotocol<NST>& that) : object_([that.object_ retain]) {}
46
47 template <typename NSU>
48 scoped_nsprotocol(const scoped_nsprotocol<NSU>& that) : object_([that.get() retain]) {}
49
50 ~scoped_nsprotocol() { [object_ release]; }
51
53 reset([that.get() retain]);
54 return *this;
55 }
56
57 void reset(NST object = nil) {
58 // We intentionally do not check that object != object_ as the caller must
59 // either already have an ownership claim over whatever it passes to this
60 // method, or call it with the |RETAIN| policy which will have ensured that
61 // the object is retained once more when reaching this point.
62 [object_ release];
63 object_ = object;
64 }
65
66 bool operator==(NST that) const { return object_ == that; }
67 bool operator!=(NST that) const { return object_ != that; }
68
69 operator NST() const { return object_; }
70
71 NST get() const { return object_; }
72
73 void swap(scoped_nsprotocol& that) {
74 NST temp = that.object_;
75 that.object_ = object_;
76 object_ = temp;
77 }
78
79 // Shift reference to the autorelease pool to be released later.
80 NST autorelease() { return [release() autorelease]; }
81
82 private:
83 NST object_;
84
85 // scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a
86 // wrapper for [object_ release]. To force a scoped_nsprotocol<> to call
87 // [object_ release], use scoped_nsprotocol<>::reset().
88 [[nodiscard]] NST release() {
89 NST temp = object_;
90 object_ = nil;
91 return temp;
92 }
93};
94
95// Free functions
96template <class C>
98 p1.swap(p2);
99}
100
101template <class C>
102bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
103 return p1 == p2.get();
104}
105
106template <class C>
107bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
108 return p1 != p2.get();
109}
110
111template <typename NST>
112class scoped_nsobject : public scoped_nsprotocol<NST*> {
113 public:
114 explicit scoped_nsobject(NST* object = nil) : scoped_nsprotocol<NST*>(object) {}
115
117
118 template <typename NSU>
120
123 return *this;
124 }
125};
126
127// Specialization to make scoped_nsobject<id> work.
128template <>
130 public:
131 explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
132
134
135 template <typename NSU>
137
140 return *this;
141 }
142};
143
144// Do not use scoped_nsobject for NSAutoreleasePools, use
145// ScopedNSAutoreleasePool instead. This is a compile time check. See details
146// at top of header.
147template <>
148class scoped_nsobject<NSAutoreleasePool> {
149 private:
150 explicit scoped_nsobject(NSAutoreleasePool* object = nil);
152};
153
154} // namespace base
155
156#endif // FLUTTER_BASE_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
scoped_nsobject & operator=(const scoped_nsobject< id > &that)
scoped_nsobject(const scoped_nsobject< id > &that)
scoped_nsobject(const scoped_nsobject< NSU > &that)
scoped_nsobject(NST *object=nil)
scoped_nsobject(const scoped_nsobject< NSU > &that)
scoped_nsobject(const scoped_nsobject< NST > &that)
scoped_nsobject & operator=(const scoped_nsobject< NST > &that)
scoped_nsprotocol(const scoped_nsprotocol< NSU > &that)
scoped_nsprotocol(const scoped_nsprotocol< NST > &that)
void swap(scoped_nsprotocol &that)
bool operator!=(NST that) const
bool operator==(NST that) const
void reset(NST object=nil)
scoped_nsprotocol & operator=(const scoped_nsprotocol< NST > &that)
scoped_nsprotocol(NST object=nil)
bool operator==(C p1, const scoped_nsprotocol< C > &p2)
void swap(scoped_nsprotocol< C > &p1, scoped_nsprotocol< C > &p2)
bool operator!=(C p1, const scoped_nsprotocol< C > &p2)
const uintptr_t id
#define BASE_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:8