Re: [Pyobjc-dev] Controller Layer
Brought to you by:
ronaldoussoren
From: Bob I. <bo...@re...> - 2003-12-02 05:41:10
|
On Dec 1, 2003, at 8:08 PM, b.bum wrote: > > On Dec 1, 2003, at 4:48 PM, Carlos Phillips wrote: >>> Try adding... >>> >>> def automaticallyNotifiesObserversForKey_(self, aKey): >>> return NO >>> >>> ... to your class and see if that fixes the problem. Also, make >>> sure you are running pyobjc based on the latest source from CVS -- >>> there have been many updates that are 10.3 specific. >>> >>> Finally, we should continue this on pyobjc-dev. I'm really busy @ >>> Apple and will likely not have time to answer you in the coming days >>> -- but the folks on pyobjc-dev will answer and they are really >>> friendly/knowledgeable. >> >> Overloading the method did in fact fix the problem. I thought this >> might be useful to someone else. > > This appears to be because of the method swizzling that occurs because > of key-value observing [KVO]. It causes an infinite loop in the > bridge. > > You can still use KVO, though. You just need to call... > > - (void)willChangeValueForKey:(NSString *)key; > - (void)didChangeValueForKey:(NSString *)key; > > ... or ... > > - (void)willChange:(NSKeyValueChange)change > valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key; > - (void)didChange:(NSKeyValueChange)change valuesAtIndexes:(NSIndexSet > *)indexes forKey:(NSString *)key; > > ... before/after the value is changed. Alternatively you can implement the accessors (and make sure that your instance variables aren't keyName or _keyName).. here's a snippet of something I have: def KVC(fn): n = fn.__name__.split('_') if len(n) == 1: if n[0].startswith('countOf'): return selector(fn, signature=NSArray.count.signature) elif len(n) == 2: if n[0].startswith('objectIn') and n[0].endswith('AtIndex') and not n[1]: return selector(fn, signature=NSArray.objectAtIndex_.signature) elif n[0].startswith('removeObjectFrom') and n[0].endswith('AtIndex') and not n[1]: return selector(fn, signature=NSMutableArray.removeObjectAtIndex_.signature) elif len(n) == 3: if n[0] == 'insertObject' and n[1].startswith('in') and n[1].endswith('AtIndex') and not n[2]: return selector(fn, signature=NSMutableArray.insertObject_atIndex_.signature) elif n[0].startswith('replaceObjectIn') and n[0].endswith('AtIndex') and n[1] == 'withObject' and not n[2]: return selector(fn, signature=NSMutableArray.replaceObjectAtIndex_withObject_) class PyNNTPConnectionWindowController(NibClassBuilder.AutoBaseClass): # this is heavily sliced and diced def init(self): self._groups = [] # key value coding compliance for group array def groupArray(self): return self._groups def countOfGroupArray(self): return len(self._groups) countOfGroupArray = KVC(countOfGroupArray) def objectInGroupArrayAtIndex_(self, index): return self._groups[index] objectInGroupArrayAtIndex_ = KVC(objectInGroupArrayAtIndex_) def insertObject_inGroupArrayAtIndex_(self, obj, index): self._groups.insert(index, obj) insertObject_inGroupArrayAtIndex_ = KVC(insertObject_inGroupArrayAtIndex_) def removeObjectFromGroupArrayAtIndex_(self, index): del self._groups[index] removeObjectFromGroupArrayAtIndex_ = KVC(removeObjectFromGroupArrayAtIndex_) and then elsewhere in the code I use self.groupsController.addObjects_(...) instead of manually doing the notifications.. although in one place I do: self.willChangeValueForKey_(u"groupArray") del self._groups[:] self.didChangeValueForKey_(u"groupArray") I'm pretty busy working on non-PyObjC stuff so I can't answer too many questions about this, but it may help (for something). -bob |