在子类中添加到超类的结构
Adding to superclass's struct in subclass
我正在使用 Mogenerator 为我的 CoreData 构建 类,我喜欢它根据 _TAGUser
的头文件中的 CoreData 属性生成的属性名称:
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
在实现文件中:
const struct TAGUserAttributes TAGUserAttributes = {
.displayName = @"displayName",
.email = @"email",
};
@implementation _TAGUser
@end
现在在子类TAGUser
中,我在头文件中添加了这个属性:
@interface TAGUser : _TAGUser {}
@property (strong, nonatomic, readonly) NSString *firstLetterOfDisplayName;
@end
这是实现文件:
@implementation TAGUser
- (NSString *)firstLetterOfDisplayName {
return ((self.displayName != nil && self.displayName.length > 0) ?
[self.displayName substringToIndex:1].uppercaseString :
nil);
}
@end
有没有一种方法可以扩展或添加到结构 TAGUserAttributes
以便我可以在代码中的其他任何地方调用 TAGUserAttributes.firstLetterOfDisplayName
进行 KVO,部分映射 NSFetchedResultsController
等等?
不能简单地扩展 C 结构。您有两种可能的方法:
对 KVO 等使用 NSStringFromSelector(firstLetterOfDisplayName)
。这样您可以获得一些编译器安全性。如果具有给定名称的选择器不存在,编译器将报错。但是,选择器可以存在于可见范围内的任何位置,而不仅仅是在您的 TagUser
class 中,以使编译器满意。
我在这里和那里看到的另一种方法是添加另一个结构,其中包含指向原始结构的指针。我现在想不出更好的命名方式,但我希望它能被理解:
在 .h 文件中:
extern const struct TAGUserAdditionalAttributes {
const struct TAGUserAttributes* base;
__unsafe_unretained NSString * firstLetterOfDisplayName;
} TAGUserAdditionalAttributes;
在 .m 文件中:
const struct TAGUserAdditionalAttributes TAGUserAdditionalAttributes = {
.base = &TAGUserAttributes,
.firstLetterOfDisplayName = @"firstLetterOfDisplayName"
};
//then you can use "base" attributes like this:
TAGUserAdditionalAttributes.base->displayName
不幸的是,指针语法让它变得很丑陋,但它仍然有效。
我正在使用 Mogenerator 为我的 CoreData 构建 类,我喜欢它根据 _TAGUser
的头文件中的 CoreData 属性生成的属性名称:
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
在实现文件中:
const struct TAGUserAttributes TAGUserAttributes = {
.displayName = @"displayName",
.email = @"email",
};
@implementation _TAGUser
@end
现在在子类TAGUser
中,我在头文件中添加了这个属性:
@interface TAGUser : _TAGUser {}
@property (strong, nonatomic, readonly) NSString *firstLetterOfDisplayName;
@end
这是实现文件:
@implementation TAGUser
- (NSString *)firstLetterOfDisplayName {
return ((self.displayName != nil && self.displayName.length > 0) ?
[self.displayName substringToIndex:1].uppercaseString :
nil);
}
@end
有没有一种方法可以扩展或添加到结构 TAGUserAttributes
以便我可以在代码中的其他任何地方调用 TAGUserAttributes.firstLetterOfDisplayName
进行 KVO,部分映射 NSFetchedResultsController
等等?
不能简单地扩展 C 结构。您有两种可能的方法:
对 KVO 等使用
NSStringFromSelector(firstLetterOfDisplayName)
。这样您可以获得一些编译器安全性。如果具有给定名称的选择器不存在,编译器将报错。但是,选择器可以存在于可见范围内的任何位置,而不仅仅是在您的TagUser
class 中,以使编译器满意。我在这里和那里看到的另一种方法是添加另一个结构,其中包含指向原始结构的指针。我现在想不出更好的命名方式,但我希望它能被理解:
在 .h 文件中:
extern const struct TAGUserAdditionalAttributes {
const struct TAGUserAttributes* base;
__unsafe_unretained NSString * firstLetterOfDisplayName;
} TAGUserAdditionalAttributes;
在 .m 文件中:
const struct TAGUserAdditionalAttributes TAGUserAdditionalAttributes = {
.base = &TAGUserAttributes,
.firstLetterOfDisplayName = @"firstLetterOfDisplayName"
};
//then you can use "base" attributes like this:
TAGUserAdditionalAttributes.base->displayName
不幸的是,指针语法让它变得很丑陋,但它仍然有效。