RLMObject.mm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 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 "RLMObject_Private.hpp"
  19. #import "RLMAccessor.h"
  20. #import "RLMArray.h"
  21. #import "RLMCollection_Private.hpp"
  22. #import "RLMObjectBase_Private.h"
  23. #import "RLMObjectSchema_Private.hpp"
  24. #import "RLMObjectStore.h"
  25. #import "RLMProperty_Private.h"
  26. #import "RLMQueryUtil.hpp"
  27. #import "RLMRealm_Private.hpp"
  28. #import "RLMSchema_Private.h"
  29. #import "object.hpp"
  30. // We declare things in RLMObject which are actually implemented in RLMObjectBase
  31. // for documentation's sake, which leads to -Wunimplemented-method warnings.
  32. // Other alternatives to this would be to disable -Wunimplemented-method for this
  33. // file (but then we could miss legitimately missing things), or declaring the
  34. // inherited things in a category (but they currently aren't nicely grouped for
  35. // that).
  36. @implementation RLMObject
  37. // synthesized in RLMObjectBase
  38. @dynamic invalidated, realm, objectSchema;
  39. #pragma mark - Designated Initializers
  40. - (instancetype)init {
  41. return [super init];
  42. }
  43. #pragma mark - Convenience Initializers
  44. - (instancetype)initWithValue:(id)value {
  45. if (!(self = [self init])) {
  46. return nil;
  47. }
  48. RLMInitializeWithValue(self, value, RLMSchema.partialPrivateSharedSchema);
  49. return self;
  50. }
  51. #pragma mark - Class-based Object Creation
  52. + (instancetype)createInDefaultRealmWithValue:(id)value {
  53. return (RLMObject *)RLMCreateObjectInRealmWithValue([RLMRealm defaultRealm], [self className], value, RLMUpdatePolicyError);
  54. }
  55. + (instancetype)createInRealm:(RLMRealm *)realm withValue:(id)value {
  56. return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyError);
  57. }
  58. + (instancetype)createOrUpdateInDefaultRealmWithValue:(id)value {
  59. return [self createOrUpdateInRealm:[RLMRealm defaultRealm] withValue:value];
  60. }
  61. + (instancetype)createOrUpdateModifiedInDefaultRealmWithValue:(id)value {
  62. return [self createOrUpdateModifiedInRealm:[RLMRealm defaultRealm] withValue:value];
  63. }
  64. + (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value {
  65. RLMVerifyHasPrimaryKey(self);
  66. return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyUpdateAll);
  67. }
  68. + (instancetype)createOrUpdateModifiedInRealm:(RLMRealm *)realm withValue:(id)value {
  69. RLMVerifyHasPrimaryKey(self);
  70. return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, RLMUpdatePolicyUpdateChanged);
  71. }
  72. #pragma mark - Subscripting
  73. - (id)objectForKeyedSubscript:(NSString *)key {
  74. return RLMObjectBaseObjectForKeyedSubscript(self, key);
  75. }
  76. - (void)setObject:(id)obj forKeyedSubscript:(NSString *)key {
  77. RLMObjectBaseSetObjectForKeyedSubscript(self, key, obj);
  78. }
  79. #pragma mark - Getting & Querying
  80. + (RLMResults *)allObjects {
  81. return RLMGetObjects(RLMRealm.defaultRealm, self.className, nil);
  82. }
  83. + (RLMResults *)allObjectsInRealm:(__unsafe_unretained RLMRealm *const)realm {
  84. return RLMGetObjects(realm, self.className, nil);
  85. }
  86. + (RLMResults *)objectsWhere:(NSString *)predicateFormat, ... {
  87. va_list args;
  88. va_start(args, predicateFormat);
  89. RLMResults *results = [self objectsWhere:predicateFormat args:args];
  90. va_end(args);
  91. return results;
  92. }
  93. + (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args {
  94. return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
  95. }
  96. + (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat, ... {
  97. va_list args;
  98. va_start(args, predicateFormat);
  99. RLMResults *results = [self objectsInRealm:realm where:predicateFormat args:args];
  100. va_end(args);
  101. return results;
  102. }
  103. + (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat args:(va_list)args {
  104. return [self objectsInRealm:realm withPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
  105. }
  106. + (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate {
  107. return RLMGetObjects(RLMRealm.defaultRealm, self.className, predicate);
  108. }
  109. + (RLMResults *)objectsInRealm:(RLMRealm *)realm withPredicate:(NSPredicate *)predicate {
  110. return RLMGetObjects(realm, self.className, predicate);
  111. }
  112. + (instancetype)objectForPrimaryKey:(id)primaryKey {
  113. return RLMGetObject(RLMRealm.defaultRealm, self.className, primaryKey);
  114. }
  115. + (instancetype)objectInRealm:(RLMRealm *)realm forPrimaryKey:(id)primaryKey {
  116. return RLMGetObject(realm, self.className, primaryKey);
  117. }
  118. #pragma mark - Other Instance Methods
  119. - (BOOL)isEqualToObject:(RLMObject *)object {
  120. return [object isKindOfClass:RLMObject.class] && RLMObjectBaseAreEqual(self, object);
  121. }
  122. - (instancetype)freeze {
  123. return RLMObjectFreeze(self);
  124. }
  125. - (BOOL)isFrozen {
  126. return _realm.isFrozen;
  127. }
  128. - (RLMNotificationToken *)addNotificationBlock:(RLMObjectChangeBlock)block {
  129. return RLMObjectAddNotificationBlock(self, block, nil);
  130. }
  131. - (RLMNotificationToken *)addNotificationBlock:(RLMObjectChangeBlock)block
  132. queue:(nonnull dispatch_queue_t)queue {
  133. return RLMObjectAddNotificationBlock(self, block, queue);
  134. }
  135. + (NSString *)className {
  136. return [super className];
  137. }
  138. #pragma mark - Default values for schema definition
  139. + (NSArray *)indexedProperties {
  140. return @[];
  141. }
  142. + (NSDictionary *)linkingObjectsProperties {
  143. return @{};
  144. }
  145. + (NSDictionary *)defaultPropertyValues {
  146. return nil;
  147. }
  148. + (NSString *)primaryKey {
  149. return nil;
  150. }
  151. + (NSArray *)ignoredProperties {
  152. return nil;
  153. }
  154. + (NSArray *)requiredProperties {
  155. return @[];
  156. }
  157. + (bool)_realmIgnoreClass {
  158. return false;
  159. }
  160. @end
  161. @implementation RLMDynamicObject
  162. + (bool)_realmIgnoreClass {
  163. return true;
  164. }
  165. + (BOOL)shouldIncludeInDefaultSchema {
  166. return NO;
  167. }
  168. - (id)valueForUndefinedKey:(NSString *)key {
  169. return RLMDynamicGetByName(self, key);
  170. }
  171. - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
  172. RLMDynamicValidatedSet(self, key, value);
  173. }
  174. + (RLMObjectSchema *)sharedSchema {
  175. return nil;
  176. }
  177. @end
  178. BOOL RLMIsObjectOrSubclass(Class klass) {
  179. return RLMIsKindOfClass(klass, RLMObjectBase.class);
  180. }
  181. BOOL RLMIsObjectSubclass(Class klass) {
  182. return RLMIsKindOfClass(class_getSuperclass(class_getSuperclass(klass)), RLMObjectBase.class);
  183. }