Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标C-覆盖setter以接受不同类型的对象_Objective C_Ios - Fatal编程技术网

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

Objective c 目标C-覆盖setter以接受不同类型的对象,objective-c,ios,Objective C,Ios,我试图覆盖NSManagedObject的setter,以便传入不同类型的对象,进行转换,然后设置属性。大概是这样的: - (void)setContentData:(NSData *)contentData { NSString *base64String; // do some stuff to convert data to base64-encoded string // ... [self willChangeValueForKey:@"contentD

我试图覆盖
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"];
}
- (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"];
    }
}
因此,在本例中,我的
NSManagedObject
contentData
字段是一个
NSString*
,我想让setter接受一个
NSData*
,然后将其转换为
NSString*
,并保存到模型中。但是,如果我尝试这样做,编译器会警告我试图将
NSData*
分配给
NSString*

myObject.contentData = someNSData;

-> Incompatible pointer types assigning to 'NSString *' from 'NSData *__strong'
有没有更好的方法来实现这一点,或者我应该完全避免使用setter,创建自定义的“setter”,允许我传入
NSData*
,并在没有编译器警告的情况下设置
NSString*
字段?

继续我的“
setContentData:(id)contentData
”注释,试着这样做:

- (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"];
}
- (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的“
@synthesis
”位,同时创建一个“getter”方法,并且因为您正在使用“
id
”作为setter参数,您可能需要稍微调整“
@property
”声明。我还没有完全尝试过您想要做的事情(即此技术没有任何保证)。

在我的“
setContentData:(id)contentData
”注释之后,请尝试以下内容:

- (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"];
}
- (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的“
@synthesis
”位,同时创建一个“getter”方法,并且因为您正在使用“
id
”作为setter参数,您可能需要稍微调整“
@property
”声明。我还没有完全尝试过你想要做的事情(也就是说,对这项技术没有任何保证)。

我认为这是一个你与工具和框架的斗争是一种重要的设计味道的例子。不要试图覆盖类的基本属性的预期数据类型

您没有说您正在子类化的NSManagedObject是否在您的控制之下。如果将其作为管理NSString以外的其他contentData类型的模板是您设计的一部分,那么在根类中将其声明为类型id并专门化子类。这应该可以避免警告


也许,您希望遵循一种协同主义:不要子类化。通过将超类提取到每个不同的行为管理对象类作为属性持有的helper类中,您能否从超类中实现所需的任何功能?

我认为这是一个与工具和框架斗争的实例,这是一个重要的设计气味。不要试图覆盖类的基本属性的预期数据类型

您没有说您正在子类化的NSManagedObject是否在您的控制之下。如果将其作为管理NSString以外的其他contentData类型的模板是您设计的一部分,那么在根类中将其声明为类型id并专门化子类。这应该可以避免警告


也许,您希望遵循一种协同主义:不要子类化。通过将超类提取到每个不同的行为管理对象类作为属性持有的帮助器类中,您能否从超类中实现所需的任何功能?

。对,重载在这里很好,但不幸的是不可能。您可以执行“
setContentData:(id)contentData
”作为一个方法签名。是的,我试过了,但仍然得到了警告。对,重载在这里很好,但不幸的是不可能。您可以将“
setContentData:(id)contentData
”作为方法签名,虽然。是的,我试过了,但还是得到了警告。这是一个NSManagedObject,所以我想避免删除@property和@dynamic内容。我不是说删除“
@property
”声明,你需要它。但是如果你想提供你自己的setter&getter,你需要删除自动为你创建setter&getter的“
@synthetic
”行。这是一个NSManagedObject,所以我想避免删除@property和@dynamic的东西。我不是说删除“
@property
”声明,你需要它。但是,如果您想提供自己的setter&getter,则需要删除自动为您创建setter&getter的“
@synthetic
”行。谢谢,我喜欢您将帮助器类设置为NSManagedObjects上的属性的想法。为了澄清,我更多的是从另一个角度考虑它:父NSManagedObject有什么值得子类化的地方?让“MyObject2”成为“MyObject1”的子类,你会得到什么?在这种情况下,你将获得当值改变时发生的所有“魔力”,我调用,例如,[self-willChangeValueForKey:@“contentData”];但是,例如,您可以实现另一个NSManagedObject类,该类也有一个“contentData”属性,在其情况下,该属性是NSData*而不是NSString。在我的例子中,contentData之所以是NSString,是因为我正在与web服务接口,将二进制数据视为base64编码字符串。我使用RestKit来管理核心数据的序列化、反序列化和连接。最后,我只是简单地使用自定义的setter和getter,比如
-(void)setContentDataWithData:(NSData*)contentData
-(NSData*)dataFromContentData
。关于这种方法的想法?谢谢,我喜欢你关于在NSManagedObject上设置为属性的helper类的想法。为了澄清,我更多地从另一个角度考虑它:父NSManagedObject有什么值得子类化的地方?你从h中得到了什么