无法子类化UIColor?

3
我是一名能帮忙翻译文本的助手。

我尝试着创建UIColor的子类,但似乎无法找出问题所在。

在我的PColor.h文件中:

#import <Foundation/Foundation.h>
@interface PColor : UIColor {
    BOOL isAvailable;
    int colorId;
}
@property (nonatomic, assign) BOOL isAvailable;
@property (nonatomic, assign) int colorId;
@end

...并且在我的 PColor.m 文件中

#import "PColor.h"

@implementation PColor
@synthesize isAvailable;
@synthesize colorId;
@end

在实例化PColor对象时,我得到:
//warning: incompatible Objective-C types initializing 'struct UIColor *', expected 'struct PColor *'
PColor *pcolor = [[PColor alloc] initWithHue:1 saturation:0 brightness:0 alpha:1];

我有点不明白,请问是否遗漏了什么?谢谢。
4个回答

6

UIColor是一个类簇,使用关联引用在一个类别中添加属性!UIColor上的所有自定义初始化方法都返回一个UIColor*而不是id,因此您不能轻松地对UIColor进行子类化,也不应该尝试。

UIColor+PCOLOR.h

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@interface UIColor(PCOLOR)
//Properties prefixed to try and avoid future conflicts
@property (nonatomic, assign) BOOL pIsAvailable;
@property (nonatomic, assign) int pColorId;
@end

UIColor+PCOLOR.h

#import "UIColor+PCOLOR.h"

@implementation UIColor(PCOLOR)

static char PCOLOR_ISAVAILABLE_KEY;
static char PCOLOR_COLORID_KEY;

@dynamic pIsAvailable, pColorId;

-(void)setPIsAvailable:(BOOL)pIsAvailable
{
    objc_setAssociatedObject(self, &PCOLOR_ISAVAILABLE_KEY, [NSNumber numberWithBool:pIsAvailable], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(BOOL)pIsAvailable
{
    return [(NSNumber*)objc_getAssociatedObject(self, &PCOLOR_ISAVAILABLE_KEY) boolValue];
}

-(void)setPColorId:(int)pColorId
{
    objc_setAssociatedObject(self, &PCOLOR_COLORID_KEY, [NSNumber numberWithInt:pColorId], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(int)pColorId
{
    return  [(NSNumber*)objc_getAssociatedObject(self, &PCOLOR_COLORID_KEY) intValue];
}

@end

使用方法

UIColor *pcolor = [[UIColor alloc] initWithHue:1 saturation:0 brightness:0 alpha:1];
pcolor.pColorId = 2352;
pcolor.pIsAvailable = YES;
NSLog(@"\nClass: %@\nColor ID: %d\nIs Availabled: %@", 
      NSStringFromClass([pcolor class]), 
      pcolor.pColorId, 
      pcolor.pIsAvailable ? @"YES" : @"NO");
[pcolor release];

这是一个非常详尽的回答...谢谢Joe。关联引用=棒极了。 - Chazbot
不错的回答。有一个问题,为什么这里使用OBJC_ASSOCIATION_RETAIN_NONATOMIC来处理布尔值?OBJC_ASSOCIATION_ASSIGN不就足够了吗? - ShivaPrasad
@jeeva 如果你看一下,你只能将对象作为关联对象存储,所以BOOL需要被包装在一个NSNumber中,然后需要被保留。 - Joe

5

来自UIColor类参考文档

大多数开发者不需要子类化UIColor。唯一需要这样做的情况是如果您需要支持其他颜色空间或颜色模型。

您应该使用Category。例如:

@interface UIColor (PColor)
    - (BOOL) isAvailable;
    - (int) colorId;
@end

在实现文件中:
@implementation UIColor (PColor)

    - (BOOL)isAvailable {
        // do what you want to do
        // return your BOOL
    }

    - (int)colorId  {
        // do what you want to do
        // return id of color
    }

@end

1
同意。我觉得一个分类更合适,黑蛙的例子对你的需求非常适用。 - Hobbes the Tige
非常感谢大家的回复 - 提供了很棒的信息。 - Chazbot
抱歉,黑蛙,但这一次我得把它给乔,因为他对关联引用的解释非常好。非常感谢你。 - Chazbot

1
因为UIColor的分配可能不会按照您的期望进行:分配一个UIColor实例。它可能是一种工厂方法,首先查看已经使用过的颜色或属于标准颜色集合,并返回它们,而不是创建新的实例。在这种情况下,您将获得UIColor而不是PColors,这意味着继承UIColor并不是一个好主意。
更倾向于组合而非继承 - 在PColor中嵌入UIColor。或者在UIColor上使用一个分类(在这种情况下,您不能有新的实例变量)。

0
UIColor的init方法返回一个UIColor*而不是大多数类使用的id,因此您必须将其分配给UIColor而不是您的子类,以避免警告。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接