Objective C类继承与工厂方法

时间:2013-06-17 09:51:30

标签: iphone objective-c oop inheritance

我想从具有工厂方法的框架类继承。如何使工厂方法返回我继承的类类型的对象?我发现this useful article描述了类似的情况,但在他们的情况下,你可以控制超类。我怎么能写一个UIImage的子类,imageNamed:会返回我的子类类型的对象?

3 个答案:

答案 0 :(得分:9)

  

我想从具有工厂方法的框架类继承。如何使工厂方法返回我继承的类类型的对象?

这是 必须做的所有事情:

@interface MONImage : UIImage
@end

@implementation MONImage
@end

然后:

MONImage * image = [MONImage imageNamed:name];

  

我怎么能写一个UIImage的子类imageNamed:会返回我的子类类型的对象?

+[UIImage imageNamed:]的实现从这种方法中编写了子类。因此,您需要自己实现此方法。

以下是声明工厂方法的方式:

+ (instancetype)imageNamed:(NSString *)pName;

以及应如何实现它:

+ (instancetype)imageNamed:(NSString *)pName
{
  MONImage * image = [[self alloc] initWithThisDesignatedInitializer:pName];
                       ^^^^ NOTE: self, not a concrete class
  ...set up image...
  return image;
}

但他们并没有这样做 - +[UIImage imageNamed:]编写了子类,并在编写UIImage时返回MONImage * img = [MONImage imageNamed:pName];。有时这是有充分理由的。有些方法应该有最终的'语义。当您的方法可能返回多个类型时,通常会出现这种情况,如在类集群中。该语言不表达“最终”#39;方法 - 但至少应记录这种方法。


所以来看看这个UIImage案例:

@interface MONImage : UIImage

+ (instancetype)imageNamed:(NSString *)pName;

@end

@implementation MONImage

+ (instancetype)imageNamed:(NSString *)pName
{
    UIImage * source = [UIImage imageNamed:pName];
    CGImageRef cgImage = source.CGImage;
    if (cgImage)
        return [[self alloc] initWithCGImage:cgImage];
    // try it another way
    return nil;
}

@end

请注意UIImageCGImage是不可变的。这不应导致图像数据的深层复制。

答案 1 :(得分:2)

对于你的例子:

  • 子类UIImage,比方说,MyImage
  • 实施imageNamed:方法,以执行您需要完成的任何具体操作。
  • 在该课程上调用该方法:MyImage *newImage = [MyImage imageNamed:imageName];

答案 2 :(得分:0)

解决我的问题的方法是使用一个类别而不是继承(在我的问题的评论中称为Jonathan Cichon)。我使用Associative References在类别实现中声明和存储其他数据,正如SO中所讨论的那样。我想提请注意Jonathan提出的NSObject category implementation,它可以非常简单和优雅地为任何对象添加关联引用。