Я думаю, что проблема в том, что вы пытаетесь использовать класс в качестве экземпляра.
У вас есть
Class unknown_cls
, и вам действительно нужен экземпляр неизвестного класса для использованияв качестве цели для регистрации КВО.
id compass = [[NSClassFromString(CompassName) alloc] init];
Теперь вы можете использовать переменную 'compass' для регистрации наблюдателей KVO.
Просто чтобы прояснить мое понимание ваших классов и их отношений:
AnalogCompass
- это класс, который выступает в качестве наблюдателя одного или нескольких Sensor
.Когда создается экземпляр AnalogCompass
, он должен регистрироваться как наблюдатель для именованного класса Sensor
.
Класс Sensor
объявляет одно свойство, которое можно наблюдать: depthInFeet
Если это точное представление ваших двух классов, ваш код никогда не будет работать.Ваш экземпляр AnalogCompass не получает ссылок на экземпляры датчика, которые он должен наблюдать.Вы также пытаетесь наблюдать свойство (xposition
), которое никогда не было объявлено наблюдаемым свойством Sensor.
Я предполагаю, что в вашем приложении есть по крайней мере один экземпляр AnalogCompass и один экземпляр Sensor.Предполагается, что экземпляр AnalogCompass наблюдает за изменениями в экземпляре датчика.
Чтобы эта работа работала с использованием 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
Если вы хотите выполнить настройку KVO в инициализаторе AnalogCompass, как, кажется, ваш код делает выше, вам нужночто-то вроде этого:
@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, вам нужно объявить общий подкласс (например, Sensor
), который имеет свойство, которое вы хотите наблюдать (например xposition
).Альтернативно вы можете определить @protocol, который реализуют все классы Sensor, который, в свою очередь, определяет свойство, которое вы хотите наблюдать.
Я думаю, что вы можете избежать использования отражения / самоанализа.Ваше приложение будет иметь коллекцию датчиков и некоторое количество объектов Compass, живых во время выполнения.Что-то в вашем приложении будет отслеживать их (например, какой-то другой объект или делегат приложения поддерживает NSArray или NSSet датчиков и / или компасов.
Возможно, ваш класс Compass собирается создать свой собственныйвнутренний объект Sensor в его инициализаторе? Из вашего кода не совсем понятно, что происходит. Однако в какой-то момент вам понадобится один объект Compass и один объект Sensor для регистрации KVO между ними.