用Swift编写的UIViewController可以作为用ObjC编写的Object的Observer

时间:2015-12-28 18:42:52

标签: ios objective-c swift key-value-observing

我正在尝试观察用ObjectiveC编写的对象中NSMutableArray的值更改。然而,观察者是用Swift编写的UIViewController。 我无法获得KVO通知。这些是我的改变:

@interface Record : BaseObject
@property (nonatomic) NSMutableArray *commentsArray;


-(NSUInteger) countOfCommentsArray {
    return _commentsArray.count;
}
-(id) objectInCommentsArrayAtIndex:(NSUInteger)index {
    return [_commentsArray objectAtIndex:index];
}
-(void) insertObject:(Comment *)comment inCommentsAtIndex:(NSUInteger)index {
    [_commentsArray insertObject:comment atIndex:index];
}

-(void) insertComments:(NSArray *)array atIndexes:(NSIndexSet*)indexes {
    [_commentsArray insertObjects:array atIndexes:indexes];
}

-(void) removeCommentsAtIndexes:(NSIndexSet *)indexes {
    [_commentsArray removeObjectsAtIndexes:indexes];
}

-(void) removeObjectFromCommentsAtIndex:(NSUInteger)index {
    [_commentsArray removeObjectAtIndex:index];
}
-(void) replaceObjectInCommentsAtIndex:(NSUInteger)index withObject:(id)object {
    [_commentsArray replaceObjectAtIndex:index withObject:object];
}

BaseObject派生自NSObject

在我的Observer类中,它是一个Viewcontroller,用Swift编写,我有以下内容。

在其中一种设置方法中。

  myInspectionRecord?.addObserver(self, forKeyPath: "commentsArray", options: NSKeyValueObservingOptions.New, context: nil);

我有方法覆盖。

  override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        print("Value Changed");
    }

但不知何故,当我使用API​​本身向数组添加新对象时,似乎不会触发observeValue方法。 关于我在这里可能缺少什么的任何指示? 或者KVO在Swift和Objective C文件之间不起作用吗?

任何帮助将不胜感激。 谢谢!

1 个答案:

答案 0 :(得分:0)

您已根据Apple's KVC guide实施了多对键值编码(!)方法,但方法名称错误。

由于您的属性名为commentsArray,因此所有方法都需要包含该全名。例如,您的insertObject:inCommentsAtIndex:应命名为insertObject:inCommentsArrayAtIndex:

根据this answer,这应该免费给你KVO调用,但你必须实际调用它们:编译器似乎认识到它需要为这些方法注入所需的KVO调用。

现在你的代码问题是,你的方法都没有改变属性,即使编译器注入了KVO代码,它也会针对错误的密钥路径执行此操作({{1}而不是comments)。有两个解决方案:似乎使用那些KVC方法免费给你KVO,但我从来没有使用过这种魔法,所以我不知道它是否会起作用。不过应该这样。

如果您想以完全不同的方式修改数组,可以使用“强力”方式:自己调用KVO methods willChangeValueForKey: and didChangeValueForKey:甚至更好,willChange:valuesAtIndexes:forKey: and didChange:valuesAtIndexes:forKey:,如下所示:

commentsArray

(我喜欢使用[self willChangeValueForKey:NSStringFromSelector(@selector(commentsArray))]; // Modify commentsArray [self didChangeValueForKey:NSStringFromSelector(@selector(commentsArray))]; // or better, for an insertion: NSIndexSet *set = [NSIndexSet indexSetWithIndex:someIndex]; NSString *key = NSStringFromSelector(@selector(commentsArray)); [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:set forKey:key]; [_commentsArray insertObject:someObject atIndex:someIndex]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:set forKey:key]; 而不是NSStringFromSelector(@selector(commentsArray)),因为编译器会知道它是一个选择器,然后重构会在重命名属性时发出警告。)