Objective C类继承与工厂方法

MrT*_*rTJ 6 oop iphone inheritance objective-c

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

jus*_*tin 9

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

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

@interface MONImage : UIImage
@end

@implementation MONImage
@end
Run Code Online (Sandbox Code Playgroud)

然后:

MONImage * image = [MONImage imageNamed:name];
Run Code Online (Sandbox Code Playgroud)

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

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

这是应该如何声明工厂方法:

+ (instancetype)imageNamed:(NSString *)pName;
Run Code Online (Sandbox Code Playgroud)

如何一个应该实现它:

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

但他们没有这样做 - +[UIImage imageNamed:]写下子类并UIImage在你写的时候返回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
Run Code Online (Sandbox Code Playgroud)

请注意,UIImages和CGImages是不可变的.这不应导致图像数据的深层复制.

  • 这是否也提供了`[UIImage imageNamed:]`的缓存行为?如果没有,也许你应该在`MONImage`中存储对原始图像的引用.但非常好的解决方案. (2认同)