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

上一篇: KVO with a unknown observed object before runtime

下一篇: How are x86 uops scheduled, exactly?