RLMSwiftCollectionBase.mm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2021 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #import "RLMSwiftCollectionBase.h"
  19. #import "RLMArray_Private.hpp"
  20. #import "RLMObjectSchema_Private.h"
  21. #import "RLMObject_Private.hpp"
  22. #import "RLMObservation.hpp"
  23. #import "RLMProperty_Private.h"
  24. #import "RLMSet_Private.hpp"
  25. #import "RLMDictionary_Private.hpp"
  26. @interface RLMArray (KVO)
  27. - (NSArray *)objectsAtIndexes:(__unused NSIndexSet *)indexes;
  28. @end
  29. // Some of the things declared in the interface are handled by the proxy forwarding
  30. #pragma clang diagnostic push
  31. #pragma clang diagnostic ignored "-Wincomplete-implementation"
  32. @implementation RLMSwiftCollectionBase
  33. + (id<RLMCollection>)_unmanagedCollection {
  34. return nil;
  35. }
  36. + (Class)_backingCollectionType {
  37. REALM_UNREACHABLE();
  38. }
  39. - (instancetype)init {
  40. return self;
  41. }
  42. - (instancetype)initWithCollection:(id<RLMCollection>)collection {
  43. __rlmCollection = collection;
  44. return self;
  45. }
  46. - (id<RLMCollection>)_rlmCollection {
  47. if (!__rlmCollection) {
  48. __rlmCollection = self.class._unmanagedCollection;
  49. }
  50. return __rlmCollection;
  51. }
  52. - (BOOL)isKindOfClass:(Class)aClass {
  53. return [self._rlmCollection isKindOfClass:aClass] || RLMIsKindOfClass(object_getClass(self), aClass);
  54. }
  55. - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
  56. return [(id)self._rlmCollection methodSignatureForSelector:sel];
  57. }
  58. - (void)forwardInvocation:(NSInvocation *)invocation {
  59. [invocation invokeWithTarget:self._rlmCollection];
  60. }
  61. - (id)forwardingTargetForSelector:(__unused SEL)sel {
  62. return self._rlmCollection;
  63. }
  64. - (BOOL)respondsToSelector:(SEL)aSelector {
  65. return [self._rlmCollection respondsToSelector:aSelector];
  66. }
  67. - (void)doesNotRecognizeSelector:(SEL)aSelector {
  68. [(id)self._rlmCollection doesNotRecognizeSelector:aSelector];
  69. }
  70. - (BOOL)isEqual:(id)object {
  71. if (auto collection = RLMDynamicCast<RLMSwiftCollectionBase>(object)) {
  72. if (!__rlmCollection) {
  73. return !collection->__rlmCollection.realm && collection->__rlmCollection.count == 0;
  74. }
  75. return [__rlmCollection isEqual:collection->__rlmCollection];
  76. }
  77. return NO;
  78. }
  79. - (BOOL)conformsToProtocol:(Protocol *)aProtocol {
  80. return aProtocol == @protocol(NSFastEnumeration) || [self._rlmCollection conformsToProtocol:aProtocol];
  81. }
  82. @end
  83. #pragma clang diagnostic pop
  84. @implementation RLMLinkingObjectsHandle {
  85. realm::TableKey _tableKey;
  86. realm::ObjKey _objKey;
  87. RLMClassInfo *_info;
  88. RLMRealm *_realm;
  89. RLMProperty *_property;
  90. RLMResults *_results;
  91. }
  92. - (instancetype)initWithObject:(RLMObjectBase *)object property:(RLMProperty *)prop {
  93. if (!(self = [super init])) {
  94. return nil;
  95. }
  96. // KeyPath strings will invoke this initializer with an unmanaged object
  97. // so guard against that.
  98. if (object->_realm) {
  99. auto& obj = object->_row;
  100. _tableKey = obj.get_table()->get_key();
  101. _objKey = obj.get_key();
  102. _info = object->_info;
  103. _realm = object->_realm;
  104. }
  105. _property = prop;
  106. return self;
  107. }
  108. - (instancetype)initWithLinkingObjects:(RLMResults *)linkingObjects {
  109. if (!(self = [super init])) {
  110. return nil;
  111. }
  112. _realm = linkingObjects.realm;
  113. _results = linkingObjects;
  114. return self;
  115. }
  116. - (RLMResults *)results {
  117. if (_results) {
  118. return _results;
  119. }
  120. [_realm verifyThread];
  121. auto table = _realm.group.get_table(_tableKey);
  122. if (!table->is_valid(_objKey)) {
  123. @throw RLMException(@"Object has been deleted or invalidated.");
  124. }
  125. auto obj = _realm.group.get_table(_tableKey)->get_object(_objKey);
  126. auto& objectInfo = _realm->_info[_property.objectClassName];
  127. auto& linkOrigin = _info->objectSchema->computed_properties[_property.index].link_origin_property_name;
  128. auto linkingProperty = objectInfo.objectSchema->property_for_name(linkOrigin);
  129. realm::Results results(_realm->_realm, obj.get_backlink_view(objectInfo.table(), linkingProperty->column_key));
  130. _results = [RLMLinkingObjects resultsWithObjectInfo:objectInfo results:std::move(results)];
  131. _realm = nil;
  132. return _results;
  133. }
  134. - (NSString *)_propertyKey {
  135. return _property.name;
  136. }
  137. - (BOOL)_isLegacyProperty {
  138. return _property.isLegacy;
  139. }
  140. @end