Skip to content

Commit

Permalink
Check superclass for property persistence
Browse files Browse the repository at this point in the history
A subclass can shadow a parent's property declaration, either explicitly
with a `@property` directive or implicitly by conforming to a protocol
that requires a particular property. The result is that the subclass
property record has no associated ivar (or methods), and calls to get /
set the property will fall up to the superclass's methods (backed by the
superclass's ivar).
  • Loading branch information
jmah committed Jul 29, 2015
1 parent 704673b commit 93c0a5c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
7 changes: 6 additions & 1 deletion Mantle/MTLModel.m
Expand Up @@ -232,7 +232,12 @@ + (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey
};

if (attributes->readonly && attributes->ivar == NULL) {
return MTLPropertyStorageNone;
if ([self isEqual:MTLModel.class]) {
return MTLPropertyStorageNone;
} else {
// Check superclass in case the subclass redeclares a property that falls through
return [self.superclass storageBehaviorForPropertyWithKey:propertyKey];
}
} else {
return MTLPropertyStoragePermanent;
}
Expand Down
9 changes: 9 additions & 0 deletions MantleTests/MTLModelSpec.m
Expand Up @@ -137,18 +137,27 @@

it(@"should consider primitive properties permanent", ^{
expect(@([MTLStorageBehaviorModel storageBehaviorForPropertyWithKey:@"primitive"])).to(equal(@(MTLPropertyStoragePermanent)));
expect(@([MTLStorageBehaviorModelSubclass storageBehaviorForPropertyWithKey:@"primitive"])).to(equal(@(MTLPropertyStoragePermanent)));
});

it(@"should consider object-type assign properties permanent", ^{
expect(@([MTLStorageBehaviorModel storageBehaviorForPropertyWithKey:@"assignProperty"])).to(equal(@(MTLPropertyStoragePermanent)));
expect(@([MTLStorageBehaviorModelSubclass storageBehaviorForPropertyWithKey:@"assignProperty"])).to(equal(@(MTLPropertyStoragePermanent)));
});

it(@"should consider object-type strong properties permanent", ^{
expect(@([MTLStorageBehaviorModel storageBehaviorForPropertyWithKey:@"strongProperty"])).to(equal(@(MTLPropertyStoragePermanent)));
expect(@([MTLStorageBehaviorModelSubclass storageBehaviorForPropertyWithKey:@"strongProperty"])).to(equal(@(MTLPropertyStoragePermanent)));
});

it(@"should ignore readonly properties without backing ivar", ^{
expect(@([MTLStorageBehaviorModel storageBehaviorForPropertyWithKey:@"notIvarBacked"])).to(equal(@(MTLPropertyStorageNone)));
expect(@([MTLStorageBehaviorModelSubclass storageBehaviorForPropertyWithKey:@"notIvarBacked"])).to(equal(@(MTLPropertyStorageNone)));
});

it(@"should consider properties declared in protocol, and backed by ivar in superclass, permanent", ^{
expect(@([MTLStorageBehaviorModel storageBehaviorForPropertyWithKey:@"dateFromProtocol"])).to(equal(@(MTLPropertyStoragePermanent)));
expect(@([MTLStorageBehaviorModelSubclass storageBehaviorForPropertyWithKey:@"dateFromProtocol"])).to(equal(@(MTLPropertyStoragePermanent)));
});

describe(@"merging with model subclasses", ^{
Expand Down
14 changes: 14 additions & 0 deletions MantleTests/MTLTestModel.h
Expand Up @@ -97,6 +97,20 @@ extern const NSInteger MTLTestModelNameMissing;
@property (readonly, nonatomic, weak) id weakProperty;
@property (readonly, nonatomic, strong) id strongProperty;

@property (readonly, nonatomic, copy) NSDate *dateFromProtocol;

@end

@protocol MTLDateProtocol <NSObject>

@property (readonly, nonatomic, copy) NSDate *dateFromProtocol;

@end

@interface MTLStorageBehaviorModelSubclass : MTLStorageBehaviorModel <MTLDateProtocol>

@property (readonly, nonatomic, strong) id strongProperty; // shadows superclass without providing storage

@end

@interface MTLBoolModel : MTLModel <MTLJSONSerializing>
Expand Down
6 changes: 6 additions & 0 deletions MantleTests/MTLTestModel.m
Expand Up @@ -355,6 +355,12 @@ - (id)notIvarBacked {

@end

@implementation MTLStorageBehaviorModelSubclass

@dynamic strongProperty;

@end

@implementation MTLMultiKeypathModel

#pragma mark MTLJSONSerializing
Expand Down

0 comments on commit 93c0a5c

Please sign in to comment.