Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[ios] making objective-C smart pointers support ARC #47612

Merged
merged 5 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ group("unittests") {
"//flutter/display_list:display_list_rendertests",
"//flutter/display_list:display_list_unittests",
"//flutter/flow:flow_unittests",
"//flutter/fml:fml_arc_unittests",
"//flutter/fml:fml_unittests",
"//flutter/lib/ui:ui_unittests",
"//flutter/runtime:dart_plugin_registrant_unittests",
Expand Down
2 changes: 2 additions & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
../../../flutter/fml/message_loop_unittests.cc
../../../flutter/fml/paths_unittests.cc
../../../flutter/fml/platform/darwin/cf_utils_unittests.mm
../../../flutter/fml/platform/darwin/scoped_nsobject_arc_unittests.mm
../../../flutter/fml/platform/darwin/scoped_nsobject_unittests.mm
../../../flutter/fml/platform/darwin/string_range_sanitization_unittests.mm
../../../flutter/fml/platform/win/file_win_unittests.cc
../../../flutter/fml/platform/win/wstring_conversion_unittests.cc
Expand Down
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,8 @@ ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.cc + ../.
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsobject.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_policy.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_typeref.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/string_range_sanitization.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/darwin/string_range_sanitization.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -5578,6 +5580,8 @@ FILE: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.cc
FILE: ../../../flutter/fml/platform/darwin/scoped_nsautorelease_pool.h
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.h
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm
FILE: ../../../flutter/fml/platform/darwin/scoped_policy.h
FILE: ../../../flutter/fml/platform/darwin/scoped_typeref.h
FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.h
FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.mm
FILE: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.cc
Expand Down
20 changes: 20 additions & 0 deletions fml/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ source_set("fml") {
"platform/darwin/scoped_nsautorelease_pool.h",
"platform/darwin/scoped_nsobject.h",
"platform/darwin/scoped_nsobject.mm",
"platform/darwin/scoped_policy.h",
"platform/darwin/scoped_typeref.h",
"platform/darwin/string_range_sanitization.h",
"platform/darwin/string_range_sanitization.mm",
]
Expand Down Expand Up @@ -366,6 +368,10 @@ if (enable_unittests) {
]
}

if (is_mac || is_ios) {
sources += [ "platform/darwin/scoped_nsobject_unittests.mm" ]
}

if (is_win) {
sources += [
"platform/win/file_win_unittests.cc",
Expand All @@ -388,4 +394,18 @@ if (enable_unittests) {
[ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
}
}

executable("fml_arc_unittests") {
testonly = true
if (is_mac || is_ios) {
cflags_objcc = flutter_cflags_objc_arc
sources = [ "platform/darwin/scoped_nsobject_arc_unittests.mm" ]
}

deps = [
":fml_fixtures",
"//flutter/fml",
"//flutter/testing",
]
}
}
92 changes: 23 additions & 69 deletions fml/platform/darwin/scoped_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,86 +8,40 @@
#include <Block.h>

#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/platform/darwin/scoped_typeref.h"

namespace fml {

// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
// Block_release() instead of CFRetain() and CFRelease().
#if defined(__has_feature) && __has_feature(objc_arc)
#define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) (__bridge TYPE)(VALUE)
#else
#define BASE_MAC_BRIDGE_CAST(TYPE, VALUE) VALUE
#endif

enum class OwnershipPolicy {
// The scoped object takes ownership of an object by taking over an existing
// ownership claim.
kAssume,
namespace fml {

// The scoped object will retain the object and any initial ownership is
// not changed.
kRetain,
};
namespace internal {

template <typename B>
class ScopedBlock {
public:
explicit ScopedBlock(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::kAssume)
: block_(block) {
if (block_ && policy == OwnershipPolicy::kRetain) {
block_ = Block_copy(block);
}
struct ScopedBlockTraits {
static B InvalidValue() { return nullptr; }
static B Retain(B block) {
return BASE_MAC_BRIDGE_CAST(
B, Block_copy(BASE_MAC_BRIDGE_CAST(const void*, block)));
}

ScopedBlock(const ScopedBlock<B>& that) : block_(that.block_) {
if (block_) {
block_ = Block_copy(block_);
}
}

~ScopedBlock() {
if (block_) {
Block_release(block_);
}
}

ScopedBlock& operator=(const ScopedBlock<B>& that) {
reset(that.get(), OwnershipPolicy::kRetain);
return *this;
}

void reset(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::kAssume) {
if (block && policy == OwnershipPolicy::kRetain) {
block = Block_copy(block);
}
if (block_) {
Block_release(block_);
}
block_ = block;
static void Release(B block) {
Block_release(BASE_MAC_BRIDGE_CAST(const void*, block));
}
};

bool operator==(B that) const { return block_ == that; }

bool operator!=(B that) const { return block_ != that; }

// NOLINTNEXTLINE(google-explicit-constructor)
operator B() const { return block_; }

B get() const { return block_; }

void swap(ScopedBlock& that) {
B temp = that.block_;
that.block_ = block_;
block_ = temp;
}
} // namespace internal

[[nodiscard]] B release() {
B temp = block_;
block_ = nullptr;
return temp;
}
// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
// Block_release() instead of CFRetain() and CFRelease().

private:
B block_;
};
template <typename B>
using ScopedBlock = ScopedTypeRef<B, internal::ScopedBlockTraits<B>>;

} // namespace fml

#undef BASE_MAC_BRIDGE_CAST

#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
Loading