我正在尝试将实例变量和属性添加到现有类中。我想这样做是为了扩展开源库的基类,而无需修改源代码(以便于代码管理)。
与常规类别不同,类扩展可以添加自己的类别 属性和类的实例变量。如果你宣布一个 类扩展中的属性[...]编译器将自动执行 合成相关的访问器方法,以及一个实例 变量,在主类实现中。
我尝试在测试应用中执行此操作。我有一个空课ClassA
:
ClassA.h
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@end
ClassA.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
实例,则它没有name
ivar。我究竟做错了什么?这实际上不可能吗?
答案 0 :(得分:3)
您的理解不正确。您通过类扩展添加了属性。此属性应该只能在您的类中使用。它不应该用作您的类的真正“属性”,您可以通过外部实例化来更改它。将其视为伪私有实例变量。
我相信你想要做的只是将你的A类继承。
提出的另一个可行的解决方案是:
“当使用objc_setAssociatedObject - &gt;时,您可以编写一个类别将其包装到 - [setAssociatedObject:forKey:]”中。来自@Artur
答案 1 :(得分:0)
我认为类扩展意味着放在class.m文件中,通常在类的@implementation之上。