Re: KVO of nested objects
Re: KVO of nested objects
- Subject: Re: KVO of nested objects
- From: Bruce Truax <email@hidden>
- Date: Fri, 29 Oct 2004 22:28:22 -0400
I read Scott's recommendation and I may implement the dictionary idea but
that will require some code restructuring. His tutorial did give me an idea
which I tried and it almost worked. To add observe a nested object I used
the construct rdPikup.surface to turn on observing for the surface key in
the rdPikup object. I add the observer using:
[surfaceArray addObserver:self
toObjectsAtIndexes: surfaceArrayIndexSet
forKeyPath:aKey
options:NSKeyValueObservingOptionNew
context:aSurface];
Where aKey is @"rdPikup.surface"
This worked. The problem came when I added a second nested key (i.e
rdPikup.scale). The key was added properly but when I tried to remove the
observer for the second nested key the program crashed with a
"EXC_BAD_ACCESS" in
[surfaceArray removeObserver:self
fromObjectsAtIndexes: surfaceArrayIndexSet
forKeyPath:aKey];
I add and remove a large number of keys using these same two functions and
they work fine until I attempt to remove a second nested key. Should this
work? Is this a bug?
Bruce
On 10/28/04 1:28 AM, "Scott Stevenson" <email@hidden> eloquently
wrote:
>
>
On Oct 26, 2004, at 5:54 AM, Bruce Truax wrote:
>
>
> Here is the important snippets of source code.
>
[...]
>
> What confuses me is how KVO will work in this case. My masterObject
>
> holds a
>
> number of instances of the nestedObject. Each nestedObject has 4
>
> keys. For
>
> example in masterObject I have
>
>
>
> NestedObject *object1;
>
> NestedObject *object2;
>
> ...
>
> NestedObject *objectN;
>
>
>
> If I turn on observing for the key 'on' how does the VKO system know
>
> if that
>
> refers to object1, object2 etc.? Or do I somehow turn on observing for
>
> object1.on?
>
>
>
Your structure is like this:
>
-----------------
>
ACLensDataObject
>
>
ACSurface x (n)
>
>
ACPikupData x (16 exactly)
>
>
BOOL isOn;
>
-----------------
>
>
>
>
With this code:
>
-----------------
>
@implementation ACLensDataObject
>
>
-
>
(void)addObserversForAllSurfaceKeysAtSurface:(int)observerSurfaceNumber
>
{
>
...
>
[surfaceArray addObserver:self
>
toObjectsAtIndexes: surfaceArrayIndexSet
>
forKeyPath:@"isOn"
>
options:NSKeyValueObservingOptionNew
>
context:aSurface];
>
}
>
-----------------
>
>
>
What this does is attempt to register for notifications on the key
>
"isOn" in the ACSurfaces. Obviously, this won't work. :)
>
>
Part of reason this whole thing seems difficult is that you have a list
>
of 16 individual hardcoded references to ACPikupData objects in each
>
ACSurface object. You should definitely move these into a dictionary
>
with keys like @"thPikup", @"rdPikup", etc. You can make the keys
>
NSString constants.
>
>
With the dictionary in place, the code could look like this:
>
>
-----------------
>
@implementation ACLensDataObject
>
>
-
>
(void)addObserversForAllSurfaceKeysAtSurface:(int)observerSurfaceNumber
>
{
>
...
>
[surfaceArray makeObjectsPerformSelector:
>
@selector(observePikupDataWithObserver:)
>
withObject: self];
>
}
>
>
@implementation ACSurface
>
>
- (void)observePikupDataWithObserver: (id)observer
>
{
>
NSArray *pikupArray = [pikupDictionary allValues];
>
>
[pikupArray addObserver:observer
>
toObjectsAtIndexes: allIndexSet // be sure to calculate this
>
first
>
forKeyPath:@"isOn"
>
options:NSKeyValueObservingOptionNew
>
context:NULL]; // not sure what you want here
>
}
>
-----------------
>
>
Also, you might want to go with something like "active" instead of "on":
>
>
- (BOOL) isActive;
>
- (void) setActive: (BOOL)newActive;
>
>
>
Hope this helps,
>
>
- Scott
>
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden