Не можете подкласс UIColor? - PullRequest
3 голосов
/ 20 апреля 2011

Я пытаюсь создать подкласс 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 голосов
/ 20 апреля 2011

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];
5 голосов
/ 20 апреля 2011

С UIColor Class Reference :

Большинству разработчиков не нужно создавать подкласс UIColor. Единственный раз, когда это может потребоваться, это если вам требуется поддержка дополнительных цветовых пространств или цветовых моделей. Вы должны использовать категорию. Например:

@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 голос
/ 20 апреля 2011

Поскольку UIColor alloc не может делать то, что вы ожидаете, он выделяет экземпляр UIColor. Это может быть своего рода фабричный метод, который сначала смотрит, какие цвета уже использованы, или принадлежит стандартному набору цветов, и возвращает его вместо создания нового экземпляра. В этом случае вы будете получать UIColor вместо PColors и что означает, что наследование UIColor не было хорошей идеей.

Предпочитайте композицию наследованию - вставьте UIColor в PColor. Или используйте категорию на UIColor (в этом случае у вас не может быть новых переменных экземпляра).

0 голосов
/ 20 апреля 2011

Методы init UIColor возвращают UIColor *, а не id, как в большинстве классов, поэтому вам придется назначить его UIColor, а не вашему подклассу, чтобы избежать предупреждения.

...