如何在不引用类的情况下调用Objective C中的+类方法?
我有一系列“策略”对象,我认为这些对象可以方便地在一组策略类中作为类方法实现。我已指定的协议对于这一点,和创建的类,以符合(只有一个如下所示)如何在不引用类的情况下调用Objective C中的+类方法?
@protocol Counter
+(NSInteger) countFor: (Model *)model;
@end
@interface CurrentListCounter : NSObject <Counter>
+(NSInteger) countFor: (Model *)model;
@end
我然后必须符合此协议(像CurrentListCounter一样)的类的数组
+(NSArray *) availableCounters {
return [[[NSArray alloc] initWithObjects: [CurrentListCounter class], [AllListsCounter class], nil] autorelease];
}
注意我如何使用对象类(这可能是我的问题 - 在Smalltalk类是像对象一样的对象 - 我不知道它们是否在Objective-C?)
我的确切的问题是当我想打电话给我的时候, licy对象从数组中:
id<Counter> counter = [[MyModel availableCounters] objectAtIndex: self.index];
return [counter countFor: self];
我得到return语句的警告 - 它说-countFor:在协议未找到(因此它假定它,我想调用类方法的实例方法)。然而,由于我的数组中的对象是类的实例,它们现在像实例方法(或概念上它们应该是)。
是否有一种神奇的方法来调用类方法?或者这只是一个坏主意,我应该创建我的策略对象的实例(而不是使用类方法)?
这
id <Counter> counter = [[Model availableCounters] objectAtIndex:0];
return ([counter countFor: nil]);
应
Class <Counter> counter = [[Model availableCounters] objectAtIndex:0];
return ([counter countFor: nil]);
在第一你必须符合<Counter>
一个实例。第二,你有一个符合<Counter>
的课程。编译器警告是正确的,因为符合<Counter>
的实例不响应countFor:
,只有类符合要求。
事实证明,它实际上工作,并且警告是不正确的。
所以问题仍然是它是否合理的事情(如果他们不需要任何状态使用类方法)?
以及如何最好地处理警告(我喜欢免费运行警告)?
我唯一的解决办法是有一个第二协议(本质上是相同的第一,但宣告它的实例侧):
@protocol CounterInstance
-(NSInteger) countFor: (Model *)model;
@end
而且在那里我访问计数器用它来代替(欺骗编译器):
id<CounterInstance> counter = [[MyModel availableCounters] objectAtIndex: self.index];
return [counter countFor: self];
它有点尴尬,但确实有效。我对其他人的看法感兴趣吗?
该警告不正确。 Objective-C的动态特性意味着消息无论如何都被发送到对象。编译器提出警告,让你知道它确实期待实例方法。至于你的解决方案 - 我觉得这很难看。只要做吉姆说的话。 – Abizern 2009-05-31 13:21:02
Objective-C中的类确实像实例一样工作 - 主要的根本区别是保留计数对它们没有任何影响。但是,存储在-availableCounters数组中的内容不是实例(类型为id
),而是类型为Class
的类。因此,与-availableCounters定义上面指定,你需要的是这样的:
Class counterClass = [[MyModel availableCounters] objectAtIndex: self.index];
return ([counterClass countFor: self]);
但是,它很可能是语义上更好,如果你使用的情况下,而不是类。在这种情况下,你可以这样做以下:你上面指定
static NSArray * globalCounterList = nil;
+ (void) initialize
{
if (self != [Model class])
return;
globalCounterList = [[NSArray alloc] initWithObjects: [[[CurrentListCounter alloc] init] autorelease], [[[SomeOtherCounter alloc] init] autorelease], nil];
}
+ (NSArray *) availableCounters
{
return (globalCounterList);
}
那么你的该用途,将是完全相同:
@protocol Counter
- (NSUInteger) countFor: (Model *) model;
@end
@interface CurrentListCounter : NSObject<Counter>
@end
@interface SomeOtherCounter : NSObject<Counter>
@end
那么你的模型类可以实现以下
id<Counter> counter = [[Model availableCounters] objectAtIndex: self.index];
return ([counter countFor: self]);
谢谢Jim - 我有兴趣看看你能推多少Objective-C。这听起来像是当你碰到类时,它开始时的行为有点不同(尽管它确实有效 - 类仍然是对象,这很好) - 所以也许它更好地坚持实例。 在评论开始的一件事情 - “类counterClass”是避免协议,而我的类也符合“计数器”。我猜想缺少的是能够正确地指定类的协议(在类一侧) - 类似于: @interface CurrentListCounter:NSObject – TimM 2009-06-01 06:34:33
您可能可以使用类counter
计数器不计数器 – 2009-05-31 12:31:10