From 8767a67dd4ca018870507a442b006032038b7889 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 25 Aug 2017 16:05:47 -0700 Subject: [PATCH] Fix more cases where assigning an RLMArray property to itself would clear the RLMArray --- CHANGELOG.md | 16 ++++++++++++++++ Realm/ObjectStore | 2 +- Realm/RLMAccessor.hpp | 2 ++ Realm/RLMAccessor.mm | 26 ++++++++++---------------- Realm/Tests/ArrayPropertyTests.m | 4 ++++ 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e89305202f..c5ec86bd8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +x.x.x Release notes (yyyy-MM-dd) +============================================================= + +### API Breaking Changes + +* None. + +### Enhancements + +* None. + +### Bugfixes + +* Fix more cases where assigning an RLMArray property to itself would clear the + RLMArray. + 2.10.0 Release notes (2017-08-21) ============================================================= diff --git a/Realm/ObjectStore b/Realm/ObjectStore index 2a715a49c4..4de03a96f8 160000 --- a/Realm/ObjectStore +++ b/Realm/ObjectStore @@ -1 +1 @@ -Subproject commit 2a715a49c4880701025684677af7e56dda857be7 +Subproject commit 4de03a96f86848297c36e89b7e9da49bf8b4d46d diff --git a/Realm/RLMAccessor.hpp b/Realm/RLMAccessor.hpp index 8ff279eda6..dc8807b26f 100644 --- a/Realm/RLMAccessor.hpp +++ b/Realm/RLMAccessor.hpp @@ -68,6 +68,8 @@ class RLMAccessorContext { RLMOptionalId default_value_for_property(realm::ObjectSchema const&, std::string const& prop); + bool is_same_list(realm::List const& list, id v) const noexcept; + template void enumerate_list(__unsafe_unretained const id v, Func&& func) { for (id value in v) { diff --git a/Realm/RLMAccessor.mm b/Realm/RLMAccessor.mm index 551ccc8c5f..8acd88d199 100644 --- a/Realm/RLMAccessor.mm +++ b/Realm/RLMAccessor.mm @@ -136,23 +136,13 @@ void setValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, __unsafe_unretained id const value) { RLMVerifyInWriteTransaction(obj); - realm::List list(obj->_realm->_realm, obj->_row.get_linklist(colIndex)); - if ([(id)value respondsToSelector:@selector(isBackedByList:)] && [(id)value isBackedByList:list]) { - return; // self-assignment is a no-op + realm::List list(obj->_realm->_realm, *obj->_row.get_table(), colIndex, obj->_row.get_index()); + RLMClassInfo *info = obj->_info; + if (list.get_type() == realm::PropertyType::Object) { + info = &obj->_info->linkTargetType(obj->_info->propertyForTableColumn(colIndex).index); } - - list.remove_all(); - if (!value || (id)value == NSNull.null) { - return; - } - - RLMAccessorContext ctx(obj->_realm, - obj->_info->linkTargetType(obj->_info->propertyForTableColumn(colIndex).index)); - translateError([&] { - for (id element in value) { - list.add(ctx, element); - } - }); + RLMAccessorContext ctx(obj->_realm, *info); + translateError([&] { list.assign(ctx, value, false); }); } void setValue(__unsafe_unretained RLMObjectBase *const obj, NSUInteger colIndex, @@ -863,3 +853,7 @@ static auto to_optional(__unsafe_unretained id const value, Fn&& fn) { { return RLMOptionalId{defaultValue(@(prop.c_str()))}; } + +bool RLMAccessorContext::is_same_list(realm::List const& list, __unsafe_unretained id const v) const noexcept { + return [v respondsToSelector:@selector(isBackedByList:)] && [v isBackedByList:list]; +} diff --git a/Realm/Tests/ArrayPropertyTests.m b/Realm/Tests/ArrayPropertyTests.m index 9bb3e09566..9549eb8106 100644 --- a/Realm/Tests/ArrayPropertyTests.m +++ b/Realm/Tests/ArrayPropertyTests.m @@ -1037,6 +1037,8 @@ - (void)testUnmanagedAssignment { // Self-assignment is a no-op array2.intArray = array2.intArray; XCTAssertEqualObjects([array2.intArray valueForKey:@"self"], (@[io2, io3])); + array2[@"intArray"] = array2[@"intArray"]; + XCTAssertEqualObjects([array2[@"intArray"] valueForKey:@"self"], (@[io2, io3])); } - (void)testManagedAssignment { @@ -1070,6 +1072,8 @@ - (void)testManagedAssignment { // Self-assignment is a no-op array2.intArray = array2.intArray; XCTAssertEqualObjects([array2.intArray valueForKey:@"intCol"], (@[@2, @3])); + array2[@"intArray"] = array2[@"intArray"]; + XCTAssertEqualObjects([array2[@"intArray"] valueForKey:@"intCol"], (@[@2, @3])); [realm cancelWriteTransaction]; }