KVO在运行前具有未知观察对象
我有一个“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)object change:(NSDictionary *)change context:(void *)context”指南针不叫。 我猜测它与反射有关,也许与这种技术的相关限制有关。 或者也许是因为反思
unknown_cls = [[NSClassFromString(super.CompassName) alloc]init];而不是与
unknown_cls = [[NSClassFromString(super.CompassName) alloc]initWithLineToParse:array];
如何让这个工作对我来说? 也许这是观察这种错误的尝试吗? 感谢帮助。
我认为这里的问题是,你正试图使用一个类作为一个实例。
你有
Class unknown_cls
而且您确实需要将未知类的实例用作KVO注册的目标。
id compass = [[NSClassFromString(CompassName) alloc] init];
现在你可以使用'compass'变量来注册KVO观察者。
只是为了澄清我对你的课程及其关系的理解:
AnalogCompass是一个充当一个或多个Sensor的观察者的类。 当创建AnalogCompass的实例时,它应该将自己注册为名为Sensor类的观察者。
Sensor类声明了一个可以观察的属性: depthInFeet
如果这是你的两个类的准确表示,你的代码将永远不会工作。 您的AnalogCompass实例没有获取它应该观察的Sensor实例的引用。 您还试图观察一个从未被声明为Sensor的可观察属性的属性( xposition )。
我假设您的应用程序中至少有一个AnalogCompass实例和一个Sensor实例。 AnalogCompass实例应该观察Sensor实例上的更改。
要使用KVO进行这项工作,您需要最低限度地做到这样的事情:
AnalogCompass *someCompass = ...;
Sensor *someSensor = ...;
/* Register someCompass as an observer of the 'xposition'
property of someSensor */
[someSensor addObserver:someCompass forKeyPath:@"xposition"
options:0 context:NULL];
您还必须声明Sensor类具有名为'xposition'的可观察属性。
@interface Sensor : NSObject
@property (nonatomic, assign) float xposition;
@end
@implementation Sensor
@synthesize xposition;
@end
如果你想在AnalogCompass的初始化程序中进行KVO设置,因为你的代码似乎在上面做了,你会想要这样的:
@interface AnalogCompass : NSObject
{
Sensor *sensor;
}
@end
@implementation AnalogCompass
- (id) initWithSensor:(Sensor *)aSensor
{
self = [super init];
if (!self) return nil;
sensor = [aSensor retain];
[sensor addObserver:self forKeyPath:@"xposition"
options:0 context:NULL];
return self;
}
- (void) dealloc
{
[sensor removeObserver:self forKeyPath:@"xposition"];
[sensor release];
[super dealloc];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"xposition"])
{
// Do something interesting with the value.
}
else
{
/* super gets to handle it */
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
@end
如果你要有多种传感器类,那么你需要声明一个具有你想要观察的属性的公共子类(例如Sensor )(例如xposition )。 您可能还可以定义所有Sensor类实现的@protocol,然后定义您想要观察的属性。
我认为你可以避免使用反思/内省。 您的应用程序将在运行时拥有一组传感器和一些Compass对象。 应用程序中的某些内容将跟踪它们(例如,某个其他对象或应用程序代理正在维护传感器和/或指南针的NSArray或NSSet。
也许你的Compass类将在其初始化器中创建自己的内部Sensor对象? 你的代码并不完全清楚发生了什么。 但是,在某些时候,您将需要一个Compass对象和一个Sensor对象,以便在它们之间注册一个KVO。
链接地址: http://www.djcxy.com/p/28163.html