我想从具有工厂方法的框架类继承。如何让工厂方法返回我继承的类类型的对象?我发现这篇有用的文章描述了类似的情况,但在他们的情况下,您可以控制超类。我怎么能写,比如说,它的子类UIImage
会imageNamed:
返回我的子类类型的对象?
3 回答
我想从具有工厂方法的框架类继承。如何让工厂方法返回我继承的类类型的对象?
这就是您应该做的所有事情:
@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
注意UIImage
s 和CGImage
s 是不可变的。这不应导致图像数据的深拷贝。
对于您的示例:
- 子类
UIImage
,比如说,MyImage
- 实现该
imageNamed:
方法以执行您需要完成的任何特定操作。 - 在该类上调用该方法:
MyImage *newImage = [MyImage imageNamed:imageName];
解决我的问题的方法是使用类别而不是继承(在我的问题的评论中归功于 Jonathan Cichon)。我使用关联引用在类别实现中声明和存储附加数据,如 SO 中所讨论的那样。我想将注意力转移到Jonathan 提出的NSObject
类别实现上,它可以非常轻松优雅地为任何对象添加关联引用。