Objective C - 覆盖setter以接受不同类型的对象

时间:2012-07-05 18:03:46

标签: objective-c ios

我正在尝试覆盖NSManagedObject的setter,以便我可以传入不同类型的对象,进行转换然后设置属性。像这样:

- (void)setContentData:(NSData *)contentData
{
    NSString *base64String;
    // do some stuff to convert data to base64-encoded string
    // ...
    [self willChangeValueForKey:@"contentData"];
    [self setPrimitiveValue:base64String forKey:@"contentData"];
    [self didChangeValueForKey:@"contentData"];
}

因此,在这种情况下,我contentData的{​​{1}}字段是NSManagedObject,我想让setter接受NSString *然后我会转换到NSData *并将其保存到模型中。但是,如果我尝试这样做,我会收到编译器关于尝试将NSString *分配给NSData *的警告:

NSString *

有没有更好的方法可以解决这个问题,或者我应该完全避免使用setter并创建自定义“setter”,这样我就可以通过myObject.contentData = someNSData; -> Incompatible pointer types assigning to 'NSString *' from 'NSData *__strong' 并设置NSData *字段而不需要编译器警告?

2 个答案:

答案 0 :(得分:3)

我认为这是一个实例,你与工具和框架的斗争是一个重要的设计气味。退出尝试覆盖您班级基本属性的预期数据类型的概念。

您没有说明您是子类化的NSManagedObject是否在您的控制之下。如果它是你的设计的一部分,让它成为管理其他类型的contentData而不是NSString的模板,那么在根类中将其声明为type id并专注于子类。这应该可以防止警告。

可能你想遵循Cocoaism:不要继承。您是否可以通过将其提取到由每个变化行为管理对象类作为属性保存的辅助类中来实现您从超类中寻找的任何功能?

答案 1 :(得分:1)

跟进我的“setContentData: (id) contentData”评论,尝试以下内容:

- (void)setContentData:(id)thingToWorkWith
{
    NSString * base64String = nil;

    if(thingToWorkWith isKindOfClass: [NSData class])
    {
       // convert data to string   
    }


    if(thingToWorkWith isKindOfClass: [NSString class])
    {
        // set up base64 string properly
    }

    if(base64String)
    {
        // do some stuff to convert data to base64-encoded string
        // ...
        [self willChangeValueForKey:@"contentData"];
        [self setPrimitiveValue:base64String forKey:@"contentData"];
        [self didChangeValueForKey:@"contentData"];
    }
}

确保在.m文件中删除contentData的“@synthesize”位,同时创建“getter”方法,并且因为您使用“id” setter参数,你可能必须稍微调整你的“@property”声明。我没有尝试过你正在尝试做的事情(即对此技术没有保证)。