首页 > 解决方案 > 如何将属性“objective-c extension”添加到实现已知协议的匿名类

问题描述

我有一个没有源的现有类,我想向该类添加一个属性。私有类实现了一个known protocol暴露的,但是class type is not exposed.

发生了一些回调,我收到了名为answer.

我想扩展 ComplexNumber 类型以具有更多属性,例如

 @interface NSObject()<ComplexNumber>
     @property (assign) BOOL offline;
 @end

 @implementation SomeClass 

 didReceiveAnswer:id<ComplexNumber>answer forEquation:(NSString*)equation {
     //
     if (answer.offline) {
        // 
     }
 }

 @end

这也失败了:强制unknown type转换为类型NSObject

     if (((NSObject*)answer).offline) {
        // 
     }

标签: objective-c

解决方案


这里似乎有两个问题:

  • 访问私人课程
  • 为其添加一个属性。

如果您知道私有类的名称,您可以简单地使用它来再次定义它:

// SomeClass.h

@interface SomeClass : NSObject <ComplexNumber>

@end

这可能看起来很奇怪,但这足以通过构建过程的编译阶段并允许您在代码中使用该属性。私有类的现有实现将足以处理链接阶段。

正如Daniele Pantaleone所指出的,第二部分非常接近Objective-C:类别中的属性/实例变量。但是我为了完整性添加了它:

// ComplexNumber.h

@protocol ComplexNumber <NSObject>
@property (assign) BOOL offline;
@end

//ComplexNumber.m

@import ObjectiveC;

@implementation NSObject (ComplexNumber)

static void *ComplexNumberKey = &ComplexNumberKey;

-(void)setOffline:(BOOL)offline
{
    objc_setAssociatedObject(self, &ComplexNumberKey, @(offline), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(BOOL)offline
{
    NSNumber *offline = objc_getAssociatedObject(self, &ComplexNumberKey);
    return offline.boolValue;
}

@end

推荐阅读