经过一番研究,我放弃使用标准的苹果对象。目前它不存在。我创建了自己的代理,它很简单(目前仅适用于“外观:”)。
让我们解释一下。
我想在NSObject子类上设置“textColor”的外观,让我们称之为“FLObject”。
使FLObject符合UIAppearance协议并覆盖外观方法。
在这个方法中,你应该返回一个代理类(我创建的那个类):
+ (id)appearance
{
return [FLAppearance appearanceForClass:[self class]];
}
它是如何工作的?
FLAppearance通过appearanceForClass:方法为每个传递的类创建一个单一实例。
如果你对同一个类调用两次,将返回同一个实例。
然后,你可以像这样做:
[[FLObject appearance] setTextColor:[UIColor redColor]]
FLAppearance覆盖了forwardInvocation:方法,因此接受所有发送的方法。
然后,它将所有调用放入一个数组中。
当FLObject被初始化时,只需简单地调用。
[(FLAppearance *)[FLAppearance appearanceForClass:[self class]] startForwarding:self]
将开始发送调用并设置外观。
当然,这需要一些调整和错误检查,但我认为这是一个不错的开端。
@interface FLAppearance ()
@property (strong, nonatomic) Class mainClass;
@property (strong, nonatomic) NSMutableArray *invocations;
@end
static NSMutableDictionary *dictionaryOfClasses = nil;
@implementation FLAppearance
+ (id) appearanceForClass:(Class)thisClass
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!dictionaryOfClasses)
dictionaryOfClasses = [[NSMutableDictionary alloc]init];
});
if (![dictionaryOfClasses objectForKey:NSStringFromClass(thisClass)])
{
id thisAppearance = [[self alloc]initWithClass:thisClass];
[dictionaryOfClasses setObject:thisAppearance forKey:NSStringFromClass(thisClass)];
return thisAppearance;
}
else
return [dictionaryOfClasses objectForKey:NSStringFromClass(thisClass)];
}
- (id)initWithClass:(Class)thisClass
{
self = [self initPrivate];
if (self) {
self.mainClass = thisClass;
self.invocations = [NSMutableArray array];
}
return self;
}
- (id)init
{
[NSException exceptionWithName:@"InvalidOperation" reason:@"Cannot invoke init. Use appearanceForClass: method" userInfo:nil];
return nil;
}
- (id)initPrivate
{
if (self = [super init]) {
}
return self;
}
-(void)forwardInvocation:(NSInvocation *)anInvocation;
{
[anInvocation retainArguments];
[self.invocations addObject:anInvocation];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [self.mainClass instanceMethodSignatureForSelector:aSelector];
}
-(void)startForwarding:(id)sender
{
for (NSInvocation *invocation in self.invocations) {
[invocation setTarget:sender];
[invocation invoke];
}
}
instancetype
而不是id
作为返回类型,这样您甚至可以跳过对FLAppearance
的显式转换。 - Gabriele Petronella