7

我想从具有工厂方法的框架类继承。如何让工厂方法返回我继承的类类型的对象?我发现这篇有用的文章描述了类似的情况,但在他们的情况下,您可以控制超类。我怎么能写,比如说,它的子类UIImageimageNamed:返回我的子类类型的对象?

4

3 回答 3

10

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

这就是您应该做的所有事情:

@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在你写的时候返回 a MONImage * img = [MONImage imageNamed:pName];。有时这样做是有充分理由的。有些方法应该具有“最终”语义。当您的方法可能返回多种类型时,这通常会出现,例如在类集群中。该语言没有表达“最终”方法——但至少应该记录这种方法。


所以来解决这个问题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

注意UIImages 和CGImages 是不可变的。这不应导致图像数据的深拷贝。

于 2013-06-19T07:42:30.460 回答
3

对于您的示例:

  • 子类UIImage,比如说,MyImage
  • 实现该imageNamed:方法以执行您需要完成的任何特定操作。
  • 在该类上调用该方法:MyImage *newImage = [MyImage imageNamed:imageName];
于 2013-06-17T09:55:36.720 回答
0

解决我的问题的方法是使用类别而不是继承(在我的问题的评论中归功于 Jonathan Cichon)。我使用关联引用在类别实现中声明和存储附加数据,如 SO 中所讨论的那样。我想将注意力转移到Jonathan 提出的NSObject类别实现上,它可以非常轻松优雅地为任何对象添加关联引用。

于 2013-06-19T07:12:10.890 回答