子类和类方法

时间:2012-10-31 12:43:44

标签: objective-c subclass uibezierpath

我想继承UIBezierPath以添加CGPoint属性。

@interface MyUIBezierPath : UIBezierPath
@property  CGPoint origin;
@end

我正在使用它:

MyUIBezierPath * path0 = [MyUIBezierPath bezierPathWithRoundedRect:
    CGRectMake(0, 0, 20, 190) byRoundingCorners:UIRectCornerAllCorners 
    cornerRadii:CGSizeMake(10, 10)];

编译器抱怨:Incompatible pointer types initializing 'MyUIBezierPath *__strong' with an expression of type 'UIBezierPath *'

bezierPathWithRoundedRect返回UIBezierPath。

所以我不能将setOrigin:发送到path0,而不是MyUIBezierPath的实例。

我应该修改什么才能让bezierPathWithRoundedRect返回我班级的实例?

编辑:在阅读相关问题之后,我觉得在这种情况下,子类化可能不是最好的做法(扩展UIBezierPath功能)。

2 个答案:

答案 0 :(得分:1)

您可以这样做的一种方法是重写子类中的方法并更改返回对象的类:

#import <objc/runtime.h>

+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
{
    UIBezierPath *path = [super bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];

    object_setClass(path, self);

    return path;
}

更简洁的方法是使用关联对象将属性添加到类别中的UIBezierPath

e.g:

static const char key;
- (CGPoint)origin
{
    return [objc_getAssociatedObject(self, &key) CGPointValue];
}

- (void)setOrigin:(CGPoint)origin
{
    objc_setAssociatedObject(self, &key, [NSValue valueWithCGPoint:origin], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

答案 1 :(得分:0)

当然,bezierPathWithRoundedRect返回一个UIBezierPath,因为它是类UIBezierPath的一个方法。您必须在新子类(MyUIBezierPath)中创建一个方法,该方法等同于显然创建该父类实例的父类之一。

但是我觉得这很难做,因为没有方法可以调用。如果没有像“initWithRoundedRect:byRoundingCorners:cornerRadii:”这样的方法,FWIK几乎是不可能的。