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 FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
6#define FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
7
8#include <type_traits>
9#include <utility>
10
11// Include NSObject.h directly because Foundation.h pulls in many dependencies.
12// (Approx 100k lines of code versus 1.5k for NSObject.h). scoped_nsobject gets
13// singled out because it is most typically included from other header files.
14#import <Foundation/NSObject.h>
15
16#include "flutter/fml/compiler_specific.h"
17#include "flutter/fml/macros.h"
18#include "flutter/fml/platform/darwin/scoped_typeref.h"
19
20#if !defined(__has_feature) || !__has_feature(objc_arc)
21@class NSAutoreleasePool;
22#endif
23
24namespace fml {
25
26// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
27// of an NSObject subclass object. Style deviations here are solely for
28// compatibility with scoped_ptr<>'s interface, with which everyone is already
29// familiar.
30//
31// scoped_nsobject<> takes ownership of an object (in the constructor or in
32// reset()) by taking over the caller's existing ownership claim. The caller
33// must own the object it gives to scoped_nsobject<>, and relinquishes an
34// ownership claim to that object. scoped_nsobject<> does not call -retain,
35// callers have to call this manually if appropriate.
36//
37// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
38// with protocols.
39//
40// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
41// NSAutoreleasePools use ScopedNSAutoreleasePool from
42// scoped_nsautorelease_pool.h instead.
43// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
44// time with a template specialization (see below).
45//
46// If Automatic Reference Counting (aka ARC) is enabled then the ownership
47// policy is not controllable by the user as ARC make it really difficult to
48// transfer ownership (the reference passed to scoped_nsobject constructor is
49// sunk by ARC and __attribute((ns_consumed)) appears to not work correctly
50// with Objective-C++ see https://llvm.org/bugs/show_bug.cgi?id=27887). Due to
51// that, the policy is always to |RETAIN| when using ARC.
52
53namespace internal {
54
55id ScopedNSProtocolTraitsRetain(__unsafe_unretained id obj)
56 __attribute((ns_returns_not_retained));
57id ScopedNSProtocolTraitsAutoRelease(__unsafe_unretained id obj)
58 __attribute((ns_returns_not_retained));
59void ScopedNSProtocolTraitsRelease(__unsafe_unretained id obj);
60
61// Traits for ScopedTypeRef<>. As this class may be compiled from file with
62// Automatic Reference Counting enable or not all methods have annotation to
63// enforce the same code generation in both case (in particular, the Retain
64// method uses ns_returns_not_retained to prevent ARC to insert a -release
65// call on the returned value and thus defeating the -retain).
66template <typename NST>
68 static NST InvalidValue() __attribute((ns_returns_not_retained)) {
69 return nil;
70 }
71 static NST Retain(__unsafe_unretained NST nst)
72 __attribute((ns_returns_not_retained)) {
74 }
75 static void Release(__unsafe_unretained NST nst) {
77 }
78};
79
80} // namespace internal
81
82template <typename NST>
84 : public ScopedTypeRef<NST, internal::ScopedNSProtocolTraits<NST>> {
85 public:
87
88#if !defined(__has_feature) || !__has_feature(objc_arc)
89 explicit scoped_nsprotocol(NST object = Traits::InvalidValue(),
92 : ScopedTypeRef<NST, Traits>(object, policy) {}
93#else
94 explicit scoped_nsprotocol(NST object = Traits::InvalidValue())
95 : ScopedTypeRef<NST, Traits>(object,
96 scoped_policy::OwnershipPolicy::kRetain) {}
97#endif
98
99 // NOLINTNEXTLINE(google-explicit-constructor)
101 : ScopedTypeRef<NST, Traits>(that) {}
102
103 template <typename NSR>
104 explicit scoped_nsprotocol(const scoped_nsprotocol<NSR>& that_as_subclass)
105 : ScopedTypeRef<NST, Traits>(that_as_subclass) {}
106
107 // NOLINTNEXTLINE(google-explicit-constructor)
109 : ScopedTypeRef<NST, Traits>(std::move(that)) {}
110
113 return *this;
114 }
115
116#if !defined(__has_feature) || !__has_feature(objc_arc)
117 void reset(NST object = Traits::InvalidValue(),
121 }
122#else
123 void reset(NST object = Traits::InvalidValue()) {
126 }
127#endif
128
129 // Shift reference to the autorelease pool to be released later.
130 NST autorelease() __attribute((ns_returns_not_retained)) {
132 }
133};
134
135// Free functions
136template <class C>
138 p1.swap(p2);
139}
140
141template <class C>
142bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
143 return p1 == p2.get();
144}
145
146template <class C>
147bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
148 return p1 != p2.get();
149}
150
151template <typename NST>
152class scoped_nsobject : public scoped_nsprotocol<NST*> {
153 public:
155
156#if !defined(__has_feature) || !__has_feature(objc_arc)
157 explicit scoped_nsobject(NST* object = Traits::InvalidValue(),
160 : scoped_nsprotocol<NST*>(object, policy) {}
161#else
162 explicit scoped_nsobject(NST* object = Traits::InvalidValue())
163 : scoped_nsprotocol<NST*>(object) {}
164#endif
165
166 // NOLINTNEXTLINE(google-explicit-constructor)
168 : scoped_nsprotocol<NST*>(that) {}
169
170 template <typename NSR>
171 explicit scoped_nsobject(const scoped_nsobject<NSR>& that_as_subclass)
172 : scoped_nsprotocol<NST*>(that_as_subclass) {}
173
174 // NOLINTNEXTLINE(google-explicit-constructor)
176 : scoped_nsprotocol<NST*>(std::move(that)) {}
177
180 return *this;
181 }
182
183#if !defined(__has_feature) || !__has_feature(objc_arc)
184 void reset(NST* object = Traits::InvalidValue(),
188 }
189#else
190 void reset(NST* object = Traits::InvalidValue()) {
192 }
193#endif
194
195#if !defined(__has_feature) || !__has_feature(objc_arc)
196 static_assert(std::is_same<NST, NSAutoreleasePool>::value == false,
197 "Use ScopedNSAutoreleasePool instead");
198#endif
199};
200
201// Specialization to make scoped_nsobject<id> work.
202template <>
204 public:
206
207#if !defined(__has_feature) || !__has_feature(objc_arc)
208 explicit scoped_nsobject(id object = Traits::InvalidValue(),
211 : scoped_nsprotocol<id>(object, policy) {}
212#else
213 explicit scoped_nsobject(id object = Traits::InvalidValue())
214 : scoped_nsprotocol<id>(object) {}
215#endif
216
217 // NOLINTNEXTLINE(google-explicit-constructor)
219 : scoped_nsprotocol<id>(that) {}
220
221 template <typename NSR>
222 explicit scoped_nsobject(const scoped_nsobject<NSR>& that_as_subclass)
223 : scoped_nsprotocol<id>(that_as_subclass) {}
224
225 // NOLINTNEXTLINE(google-explicit-constructor)
227 : scoped_nsprotocol<id>(std::move(that)) {}
228
231 return *this;
232 }
233
234#if !defined(__has_feature) || !__has_feature(objc_arc)
235 void reset(id object = Traits::InvalidValue(),
239 }
240#else
241 void reset(id object = Traits::InvalidValue()) {
243 }
244#endif
245};
246
247} // namespace fml
248
249#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
T get() const __attribute((ns_returns_not_retained))
ScopedTypeRef & operator=(const ScopedTypeRef< T, Traits > &that)
NST release() __attribute((ns_returns_not_retained))
void reset(__unsafe_unretained T object=Traits::InvalidValue(), fml::scoped_policy::OwnershipPolicy policy=fml::scoped_policy::kAssume)
void swap(ScopedTypeRef &that)
scoped_nsobject(id object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
scoped_nsobject(const scoped_nsobject< id > &that)
void reset(id object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
scoped_nsobject(const scoped_nsobject< NSR > &that_as_subclass)
scoped_nsobject & operator=(const scoped_nsobject< id > &that)
scoped_nsobject(scoped_nsobject< id > &&that)
scoped_nsobject & operator=(const scoped_nsobject< NST > &that)
scoped_nsobject(const scoped_nsobject< NST > &that)
void reset(NST *object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
scoped_nsobject(scoped_nsobject< NST > &&that)
scoped_nsobject(const scoped_nsobject< NSR > &that_as_subclass)
scoped_nsobject(NST *object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
scoped_nsprotocol & operator=(const scoped_nsprotocol< NST > &that)
scoped_nsprotocol(scoped_nsprotocol< NST > &&that)
scoped_nsprotocol(const scoped_nsprotocol< NSR > &that_as_subclass)
void reset(NST object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
scoped_nsprotocol(const scoped_nsprotocol< NST > &that)
scoped_nsprotocol(NST object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
internal::ScopedNSProtocolTraits< NST > Traits
NST autorelease() __attribute((ns_returns_not_retained))
uint8_t value
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network policy
Definition: switches.h:248
void ScopedNSProtocolTraitsRelease(__unsafe_unretained id obj)
id ScopedNSProtocolTraitsAutoRelease(__unsafe_unretained id obj) __attribute((ns_returns_not_retained))
id ScopedNSProtocolTraitsRetain(__unsafe_unretained id obj) __attribute((ns_returns_not_retained))
Definition: ascii_trie.cc:9
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)
Definition: ref_ptr.h:256
static void Release(__unsafe_unretained NST nst)
static NST InvalidValue() __attribute((ns_returns_not_retained))
static NST Retain(__unsafe_unretained NST nst) __attribute((ns_returns_not_retained))
const uintptr_t id