我有一个“Compass”类,它是另一个类“SensorA”,“SensorB”或“SensorC”的观察者 . 问题是我在运行时之前不知道观察到的类 . 我使用反射来在运行时创建实例 . 我不知道在这样做的时候我是否正确地练习KVO .
---Another Extern Class---
Compass *aCompass= [[AnalogCompass alloc] initWithCompassName:@"ABC" andID...];
---The oberserving Compass.m Class---
- (id)initWithCompassName:(NSString *)CompassName
andIid:(int)Iid
showAnalog:(NSString *)ShowAnalog
showDigital:(NSString *)ShowDigital
{
if (self = [super init])
{
super.iid = Iid;
super.CompassName = CompassName;
showAnalog=ShowAnalog;
showDigital=ShowDigital;
Class unknown_cls;
unknown_cls = [[NSClassFromString(super.CompassName) alloc]init];
[unknown_cls addObserver:self forKeyPath:showAnalog options:NSKeyValueObservingOptionNew context:NULL];
[unknown_cls addObserver:self forKeyPath:showDigital options:NSKeyValueObservingOptionNew context:NULL];
}
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
NSLog(@"IN?");
// [super observeValueForKeyPath:keyPath
//
// ofObject:object
//
// change:change
//
// context:context];
}
---Example of the oberserved SensorA Class---
@interface SensorA : NSObject {
double xPosition;
...
}
@property (assign) double depthInFeet;
- (id)initWithLineToParse:(NSArray *) fields;
@end
当我做像self.xposition = position这样的改变时;在我的任何观察和反射的传感器类(SensorA,SensorB,SensorC)中,“observeValueForKeyPath:(NSString *)keyPath ofObject :( id)对象更改:(NSDictionary *)更改上下文:(void *)context”在我的观察者中指南针不被调用 . 我猜测它与反射有关,也许与这种技术的相关限制有关 . 或者也许是因为反思
unknown_cls = [[NSClassFromString(super.CompassName) alloc]init];
而不是
unknown_cls = [[NSClassFromString(super.CompassName) alloc]initWithLineToParse:array];
如何让这个为我工作?可能是这样的错误尝试吗?感谢帮助 .
1 回答
我认为这里的问题是你试图使用Class作为实例 .
你有
并且您确实需要将未知类的实例用作KVO注册的目标 .
现在您可以使用'compass'变量来注册KVO观察者 .
只是为了澄清我对你的课程及其关系的理解:
AnalogCompass
是一个充当一个或多个Sensor
的观察者的类 . 当创建AnalogCompass
的实例时,它应该将自己注册为名为Sensor
类的观察者 .Sensor
类声明了一个可以观察到的属性:depthInFeet
如果这是您的两个类的准确表示,您的代码将永远不会工作 . 您的AnalogCompass实例没有引用它应该观察的Sensor实例 . 您还试图观察一个从未被声明为Sensor的可观察属性的属性(
xposition
) .我假设您的应用程序中至少有一个AnalogCompass实例和一个Sensor实例 . AnalogCompass实例应该观察Sensor实例的变化 .
要使用KVO来完成这项工作,您需要最低限度地执行以下操作:
您还必须声明Sensor类具有名为“xposition”的可观察属性 .
如果你想在AnalogCompass的初始值设定器中进行KVO设置,正如你的代码似乎在上面做的那样,你需要这样的东西:
如果您要使用多种Sensor类,那么您需要声明一个具有您想要观察的属性的公共子类(例如
Sensor
)(例如xposition
) . 您可以替代地定义所有Sensor类实现的@protocol,这反过来又定义了您要观察的属性 .我认为你可以避免使用反射/内省 . 您的应用程序将在运行时生成一组传感器和一些Compass对象 . 应用程序中的某些东西将跟踪它们(例如,某些其他对象或应用程序委托正在维护NSArray或NSSet传感器和/或指南针 .
也许您的Compass类将在其初始化程序中创建自己的内部Sensor对象?从您的代码中发现的情况并不完全清楚 . 但是,在某些时候,您需要一个Compass对象和一个Sensor对象才能在它们之间注册KVO .