2015-12-28 13 views
1

我试图观察在ObjectiveC中编写的对象中的NSMutableArray的值更改。然而观察者是用Swift编写的UIViewController。 我无法获得KVO通知。这些是我的更改:可以在Swift中编写的UIViewController作为ObjC中写入的对象的观察者

@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); 

而且我有方法overrriden。

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

但不知何故,当我使用API​​本身添加一个新的对象数组,被触发的observeValue方法似乎并不。 关于我可能在这里失踪的任何指针? 或者KVO不能在Swift和Objective C文件之间工作?

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

+0

相关:http://stackoverflow.com/questions/24092285/ is-key-value-observation-kvo-available-in-swift – kennytm

+0

是myInspect ionRecord'实际上指向你想要观察的代码运行的最后一个对象吗?换句话说:在'addObserver'行放置一个断点,看看'myInspectionRecord'是否为'nil'。如果您正在分配该变量,请务必在设置之前始终取消注册并重新注册。 – DarkDust

+0

顺便说一句,因为你的Swift类是从'UIViewController'(从而'从NSObject')派生的,所以KVO可以正常工作。 – DarkDust

回答

0

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

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

根据this answer这应该然后给你的志愿接听电话免费,但你必须真正给他们打电话:编译器似乎认识到它需要注入所需的国际志愿者组织调用这些方法。

现在用你的代码的问题,既不是你的方法改变财产而且即使编译器注入志愿代码,它会为错误的关键路径这样做(comments而不是commentsArray)。有两种解决方案:似乎使用那些KVC方法免费给你KVO,但我从未使用过这种魔法,所以我不知道它是否会起作用。它应该,但是。

有一个“蛮力”方式,如果你要修改的阵列在一个完全不同的方法,你可以使用:拨打KVO methods willChangeValueForKey: and didChangeValueForKey:甚至更​​好,willChange:valuesAtIndexes:forKey: and didChange:valuesAtIndexes:forKey:自己,就像这样:

[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))代替@"commentsArray"因为编译器就知道这是一个选择,然后重构会警告你,当你重命名属性,例如。)

+0

属性本身不必更改 - 只要数组通过具体命名的方法更改,您将获得有关该数组插入/删除的更改通知。你的命名虽然是对的,但这是主要问题。不错的地方。我认为,如果OP将它们修复为像'insertObject:inCommentsArrayAtIndex:'那么KVO通知将起作用。 –

+0

谢谢。这有帮助。该变量之前被命名为'comments'。猜猜这就是Xcode提出这种方法的原因。修复了方法名称并且工作。 –

相关问题