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