Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Commit 40fcfd4

Browse files
committed
Don't dirty unchanged records
If any KVO methods get called (e.g., -willChangeValueForKey: and -didChangeValueForKey:), -isUpdated will return YES even if nothing has actually changed. Here, we prune unchanged values from the updates dictionary to ensure the record will not return YES for -hasChanges unless values change in the first place. Signed-off-by: Stephen Celis <stephen@stephencelis.com>
1 parent b4d282d commit 40fcfd4

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

Classes/NSManagedObject+ActiveRecord.m

+10-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ + (instancetype)findOrCreate:(NSDictionary *)properties {
6464
}
6565

6666
+ (instancetype)findOrCreate:(NSDictionary *)properties inContext:(NSManagedObjectContext *)context {
67-
NSDictionary *transformed = [[self class] transformProperties:properties withContext:context];
67+
NSDictionary *transformed = [[self class] transformProperties:properties withObject:nil context:context];
6868

6969
NSManagedObject *existing = [self where:transformed inContext:context].first;
7070
return existing ?: [self create:transformed inContext:context];
@@ -172,7 +172,7 @@ + (id)createInContext:(NSManagedObjectContext *)context {
172172
- (void)update:(NSDictionary *)attributes {
173173
unless([attributes exists]) return;
174174

175-
NSDictionary *transformed = [[self class] transformProperties:attributes withContext:self.managedObjectContext];
175+
NSDictionary *transformed = [[self class] transformProperties:attributes withObject:self context:self.managedObjectContext];
176176

177177
for (NSString *key in transformed) [self willChangeValueForKey:key];
178178
[transformed each:^(NSString *key, id value) {
@@ -207,7 +207,7 @@ + (NSString *)entityName {
207207

208208
#pragma mark - Private
209209

210-
+ (NSDictionary *)transformProperties:(NSDictionary *)properties withContext:(NSManagedObjectContext *)context {
210+
+ (NSDictionary *)transformProperties:(NSDictionary *)properties withObject:(NSManagedObject *)object context:(NSManagedObjectContext *)context {
211211
NSEntityDescription *entity = [NSEntityDescription entityForName:[self entityName] inManagedObjectContext:context];
212212

213213
NSDictionary *attributes = [entity attributesByName];
@@ -218,7 +218,13 @@ + (NSDictionary *)transformProperties:(NSDictionary *)properties withContext:(NS
218218
for (NSString *key in properties) {
219219
NSString *localKey = [self keyForRemoteKey:key inContext:context];
220220
if (attributes[localKey] || relationships[localKey]) {
221-
transformed[localKey] = [[self class] transformValue:properties[key] forRemoteKey:key inContext:context];
221+
id value = [[self class] transformValue:properties[key] forRemoteKey:key inContext:context];
222+
if (object) {
223+
id localValue = [object primitiveValueForKey:localKey];
224+
if ([localValue isEqual:value] || (localValue == nil && value == [NSNull null]))
225+
continue;
226+
}
227+
transformed[localKey] = value;
222228
} else {
223229
#if DEBUG
224230
NSLog(@"Discarding key ('%@') from properties on class ('%@'): no attribute or relationship found",

Example/SampleProjectTests/FindersAndCreatorsTests.m

+6
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ void createSomePeople(NSArray *names, NSArray *surnames, NSManagedObjectContext
312312
}];
313313
[[[Person where:@{ @"firstName": @"asetnset" }] should] haveCountOf:1];
314314
});
315+
316+
it(@"doesn't mark records as having changes when values are the same", ^{
317+
Person *person = fetchUniquePerson();
318+
[person update:@{@"firstName": person.firstName}];
319+
[[@([person hasChanges]) should] beNo];
320+
});
315321
});
316322

317323
context(@"Saving", ^{

0 commit comments

Comments
 (0)