【问题标题】:Convert instance of a parent class into its subclass将父类的实例转换为其子类
【发布时间】:2012-05-02 20:18:43
【问题描述】:

我将 UIImage 子类化为创建 UIImageExtra。我在 UIImageExtra 中有一个名为 adjustForResolution 的方法,它可以调整 UIImage 的大小。但是我希望它返回一个 UIImageExtra。我知道我需要转换它,但不确定如何转换。基本上,如果我调整 UIImageExtra 的大小,它就会变成 UIImage。

这是我的 UIImageExtra 类:

    #import "UIImageExtra.h"
#import <objc/runtime.h>
#import "UIApplication+AppDimensions.h"

#define kOriginData     @"originData"

@implementation UIImageExtra

@synthesize originData;

+ (UIImageExtra *)imageNamed:(NSString *)imageName origin:(NSValue *)originData {
    NSString *path = [[NSBundle mainBundle] pathForResource:imageName ofType:@""];
    UIImageExtra *imageExtra = [[UIImageExtra alloc] initWithContentsOfFile:path];
    imageExtra.originData = originData;
    return imageExtra;
}

- (id)initWithContentsOfFile:(NSString *)path {
    self = [super initWithContentsOfFile:path]; 
    if (self) {
        self = [self adjustForResolution];
    }
    NSLog(@"Image description: %@", [self description]);
    return self;
}


- (id)adjustForResolution {
    //All images are sized for ipad3 (2048 x 1536), so determine scale factor by ratio
    CGSize screenSize = [UIApplication currentSize];
    double scalefactor = screenSize.width/2048;
    CGSize newSize = CGSizeMake(self.size.width*scalefactor, self.size.height*scalefactor);
    UIImage *scaledImage = [self imageByScalingAndCroppingForSize:newSize];
    return scaledImage;
}

- (id)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
   //returns resized image
}

@end

【问题讨论】:

  • 我认为您的 imageByScalingAndCroppingForSize 方法只返回一个 UIImage,因此您的 init 方法返回一个 UIImage。另外,我认为在 init 中返回 self 以外的其他对象不是一个好主意。
  • imageByScalingAndCroppingForSize: 里面有什么?您是否正在创建一个新的 UIImage 实例?
  • @JonathanCichon 是的,那么我怎样才能确保它返回一个 UIImageExtra 实例,而不是一个 UIImage?
  • @JacquesCousteau imageByScalingAndCroppingForSize:返回一个新的 UIImage 实例。我想我的问题是如何确保这些方法返回 UIImageExtra 对象?

标签: objective-c ios xcode uiimage subclassing


【解决方案1】:

创建一个 UIImage 的类扩展来处理大小调整然后创建一个从 NSObject 继承的新类来保存两个 UIImage 会更容易吗?一个是原始 UIImage,另一个是调整大小的副本?

UIImage+Extra.h:

#import <UIKit/UIKit.h>

@interface UIImage (Extra)

-(void)adjustForResolution;
-(void)imageByScalingAndCroppingForSize:(CGSize)targetSize;

@end

UIImage+Extra.m:

#import "UIImage+Extra.h"

@implementation UIImage (Extra)


- (void)adjustForResolution {
      //All images are sized for ipad3 (2048 x 1536), so determine scale factor by ratio
      CGSize screenSize = [UIApplication currentSize];
      double scalefactor = screenSize.width/2048;
      CGSize newSize = CGSizeMake(self.size.width*scalefactor,self.size.height*scalefactor);
      [self imageByScalingAndCroppingForSize:newSize];

}

- (id)imageByScalingAndCroppingForSize:(CGSize)targetSize
{

      //instead of doing work to another object and returning it... Do it to self (UIimage)

}

@end

然后在您的自定义 NSObject 类上,您的 init 可以是这样的:

#import "UIImage+Extra"

...

//initialisation 

if (self) {

     originalImage = [UIImage imageNamed:@"theimage.png"];
     resizedImage = [UIImage imageNamed:@"theimage.png"];
     [resizedImage adjustForResolution];

}

刚刚输入,所以可能有一些拼写错误,但我希望它可以帮助

【讨论】:

  • 这是一个很好的解决方案,但这实际上是一个类别而不是类扩展。
  • @L14M333 我扩展 UIImage 的原因是因为我想添加一个 iVar - originData。您不能将 iVar 添加到类别中。我还想扩展 NSCoding 方法以确保保存 originData 属性...
  • @Smikey 我注意到在我写完之后哈哈......这就是为什么我建议你将两个变量都保存在一个 NSObject 中(最后一个代码 sn-p)
  • @L14M333 哦,我明白了……但是这是否意味着没有办法让它按照我的设置工作?如果我采用这种方法,我必须创建 2 个类,而不仅仅是一个。
  • @Smikey 您可以保留 UIImageExtra 并且旁边还有 UIImage+Extra 然后让 UIImage+Extra 只执行调整大小的功能然后 UIImageExtra 类也可以调用 imageByScalingAndCroppingForSize: 如果你导入 UIImage+额外...我认为这可能有效?
【解决方案2】:

我认为这就是你想要做的:

- (id)initWithContentsOfFile:(NSString *)path {
    CGSize screenSize = [UIApplication currentSize];
    double scalefactor = screenSize.width/2048;
    if (scalefactor < 1) {
        UIImage *img = [UIImage imageWithContentsOfFile:path];
        CGSize newSize = CGSizeMake(img.size.width*scalefactor, img.size.height*scalefactor);
        UIGraphicsBeginImageContext(newSize);
        CGContextRef c = UIGraphicsGetCurrentContext();

        [img drawInRect:(CGRect){CGPointZero, newSize}];
        CGImageRef scaledImage = CGBitmapContextCreateImage(c);
        UIGraphicsEndImageContext();
        self = [super initWithCGImage:scaledImage];
        CGImageRelease(scaledImage);
    }else {
        self = [super initWithContentsOfFile:path];
    }
    return self;
}

不使用 contensOfFile 代替 initWithCGImage 的缺点是,生成的图像不可清除,因此迟早会出现内存问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多