【问题标题】:Objective C : Given a Class id, can I check if this class implements a certain protocol? Or has a certain selector?Objective C:给定一个Class id,我可以检查这个类是否实现了某个协议吗?还是有一定的选择器?
【发布时间】:2011-01-21 15:03:55
【问题描述】:

我想将它用于对象工厂:给定一个字符串,创建一个类,如果 该类支持协议(使用 Create() 方法)然后分配该类并调用 创建。

【问题讨论】:

    标签: objective-c class protocols objectfactory


    【解决方案1】:
    Class klass = NSClassFromString(classname);
    if ([klass instancesRespondToSelector:@selector(create)]) {
      [[klass alloc] create];
    }
    

    但是,我可以指出您通过执行上述操作违反了多少可怕的 Objective-C 规则吗?例如,您永远不应该在已分配但未初始化的实例上调用方法。 Xcode 静态分析器会给你各种关于内存泄漏的警告。

    更好的选择是:

    [[[klass alloc] init] create];
    

    但你似乎暗示你不想调用 init。

    您可以考虑一个类方法:[klass create],它将返回一个非拥有的 klass 实例。然后你只需在调用之前检查[klass respondsToSelector:@selector(create)]

    【讨论】:

    • 谢谢。没错,Create 方法应该是一个类方法。我认为这通常是对象工厂的设计方式。
    • 这不是最佳答案。查克更好。
    【解决方案2】:
    NSString *className; //assume this exists
    Class class = NSClassFromString(className);
    if ([class conformsToProtocol:@protocol(SomeProtocol)]) {
        id instance = [[class alloc] init];
        [instance create];
    }
    

    【讨论】:

    • 他在标题中问了两个问题:)
    • 更进一步:id<SomeProtocol> instance = [[class alloc] init]
    • 如果您没有或不知道类名,则使用 [instance class] 或 NSStringFromClass([instance class])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多