iosobjective-cmogenerator

Adding to superclass's struct in subclass


I'm using Mogenerator to build classes for my CoreData, and I love the attribute names that it generates based off CoreData attributes like this in the header file of _TAGUser:

extern const struct TAGUserAttributes {
    __unsafe_unretained NSString *displayName;
    __unsafe_unretained NSString *email;
} TAGUserAttributes;

@interface _TAGUser : NSManagedObject

@property (nonatomic, strong) NSString* displayName;
@property (nonatomic, strong) NSString* email;

@end

And this in the implementation file:

const struct TAGUserAttributes TAGUserAttributes = {
    .displayName = @"displayName",
    .email = @"email",
};

@implementation _TAGUser

@end

Now in the subclass TAGUser, I added this property to the header file:

@interface TAGUser : _TAGUser {}

@property (strong, nonatomic, readonly) NSString *firstLetterOfDisplayName;

@end

And this to the implementation file:

@implementation TAGUser

- (NSString *)firstLetterOfDisplayName {
    return ((self.displayName != nil && self.displayName.length > 0) ?
        [self.displayName substringToIndex:1].uppercaseString :
        nil);
}

@end

Is there a way I can either extend or add to the struct TAGUserAttributes so that anywhere else in my code I can call on TAGUserAttributes.firstLetterOfDisplayName for KVO, section mapping in NSFetchedResultsController, etc?


Solution

  • One does not simply extend a C struct. You have two possible approaches:

    in .h file:

    extern const struct TAGUserAdditionalAttributes {
        const struct TAGUserAttributes* base;
        __unsafe_unretained NSString * firstLetterOfDisplayName;
    } TAGUserAdditionalAttributes;
    

    in .m file:

    const struct TAGUserAdditionalAttributes TAGUserAdditionalAttributes = {
        .base = &TAGUserAttributes,
        .firstLetterOfDisplayName = @"firstLetterOfDisplayName"
    };
    
       //then you can use "base" attributes like this:
       TAGUserAdditionalAttributes.base->displayName
    

    Unfortunately the pointer syntax makes it quite ugly, but it still works.