1

我正在尝试将实例变量和属性添加到现有类。我想这样做是为了扩展一个开源库的基类,而不需要修改源代码(以便于代码管理)。

文件说_

与常规类别不同,类扩展可以将自己的属性和实例变量添加到类中。如果您在类扩展中声明属性 [...],编译器将在主类实现中自动合成相关的访问器方法以及实例变量。

我试图在一个测试应用程序中做到这一点。我有一个空课ClassA

类A.h

#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@end

类A.m

#import "ClassA.h"    
@implementation ClassA
@end


然后我添加了一个扩展:

ClassA+Ext.h

#import "ClassA.h"
@interface ClassA ()

@property (nonatomic) NSString *name;      // <-- this is my new property

@end


最后在我的AppDelegate我简单地初始化一个ClassA并尝试设置然后记录name.

#import "AppDelegate.h"
#import "ClassA.h"
#import "ClassA+Ext.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    ClassA *a = [[ClassA alloc] init];
    a.name = @"test";
    NSLog(@"Name: %@", a.name);
}

@end

这编译并运行,但我在控制台上收到此错误:

2013-05-10 00:58:08.598 Test[53161:303] -[ClassA setName:]: unrecognized selector
sent to instance 0x108a1a630
2013-05-10 00:58:08.600 Test[53161:303] -[ClassA setName:]: unrecognized selector 
sent to instance 0x108a1a630

该名称未记录。如果我设置断点并检查ClassA实例,它没有nameivar。我究竟做错了什么?这真的不可能吗?

4

2 回答 2

3

你的理解是不正确的。您通过类​​扩展添加了一个属性。这个属性应该只能在你的类中使用。它不应该用作您的类的真正“属性”,您可以在其中通过外部实例化对其进行更改。将其视为伪私有实例变量。

我相信您想要做的只是将您的 A 类子类化。

另一个可行的解决方案是:

“您可以编写一个类别以将其包装到 -[setAssociatedObject:forKey:]”当使用 objc_setAssociatedObject --> @Artur

于 2013-05-09T23:11:11.777 回答
0

我认为类扩展应该放在 class.m 文件中,通常在类的 @implementation 之上。

于 2013-05-09T23:11:11.287 回答