Can't subclass UIColor?

做~自己de王妃 提交于 2019-12-01 22:57:37

问题


I'm trying to subclass UIColor, and I can't seem to figure out what's wrong.

In my PColor.h

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

...and in my PColor.m

#import "PColor.h"

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

Upon instantiating a PColor object, I get:

//warning: incompatible Objective-C types initializing 'struct UIColor *', expected 'struct PColor *'
PColor *pcolor = [[PColor alloc] initWithHue:1 saturation:0 brightness:0 alpha:1];

Am I missing something? Thanks in advance.


回答1:


UIColor is a class cluster use associative references in a category to add properties! All of the custom init methods on UIColor return a UIColor* not an id so you can not easily subclass UIColor nor should you try.

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

USAGE

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];



回答2:


From UIColor Class Reference:

Most developers should have no need to subclass UIColor. The only time doing so might be necessary is if you require support for additional colorspaces or color models.

You should use Category. For example:

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

In the implementation file:

@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



回答3:


Because UIColor alloc might not do what you expect it to do: allocating an instance of UIColor. It may be kind of a factory method, which looks first what colors have already been used or belong to a standard set of colors and give it back instead of creating a new instance. In which case you will be getting UIColor instead of PColors and what means that inheriting UIColor was not a good idea.

Prefer composition over inheritance - embed UIColor within a PColor. Or use a category on UIColor (you can't have new instance variables in this case).




回答4:


The init methods of UIColor return a UIColor* rather than id as with most classes, so you would have to assign it to a UIColor rather than your subclass to avoid the warning.



来源:https://stackoverflow.com/questions/5731299/cant-subclass-uicolor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!