Best way to notify the Controller when one Array object value is changed
-
Hello, so i have one ArrayController that is bound to one Array, and a
tablecolumn that is bound to the ArrayController objects (not any particular
value).
As a normal behavior the controller gets notified when i add or remove
objects, but i have a thread that every second updates the objects. What is
the correct way to notify the Controller that a specific object values where
changed?
I'm guessing the Thread shouldn't have direct access to the Controller since
its in a "lower" abstraction layer, so how do i notify or make the
controller track changes to values?
The column is not bound to values because it has custom dataCells that need
several properties from the array objects.
Ty. -
Hello, so i have one ArrayController that is bound to one Array, and a
tablecolumn that is bound to the ArrayController objects (not any particular
value).
As a normal behavior the controller gets notified when i add or remove
objects, but i have a thread that every second updates the objects. What is
the correct way to notify the Controller that a specific object values where
changed?
I'm guessing the Thread shouldn't have direct access to the Controller since
its in a "lower" abstraction layer, so how do i notify or make the
controller track changes to values?
The column is not bound to values because it has custom dataCells that need
several properties from the array objects.
PS: if my previous mail really arrived im sorry, i had my mails mixed up and
used the wrong one =)
Ty. -
On Jan 29, 2008, at 6:16 PM, Miguel Coxo wrote:
> Hello, so i have one ArrayController that is bound to one Array, and a
> tablecolumn that is bound to the ArrayController objects (not any
> particular
> value).
>
> As a normal behavior the controller gets notified when i add or remove
> objects, but i have a thread that every second updates the objects.
> What is
> the correct way to notify the Controller that a specific object
> values where
> changed?
>
> I'm guessing the Thread shouldn't have direct access to the
> Controller since
> its in a "lower" abstraction layer, so how do i notify or make the
> controller track changes to values?
>
> The column is not bound to values because it has custom dataCells
> that need
> several properties from the array objects.
If you modify the array in one of the KVO-compliant ways, then the
array controller will be informed automatically. However, you should
not do so from a background thread, because the notification will be
delivered on whatever thread does the modification, and bindings will
attempt to update the GUI from the background thread, which will cause
trouble.
You can use performSelectorInMainThread:... to have the background
thread push the modification to the main thread. You may not need to
use a thread at all. Will an NSTimer meet your needs?
To perform the modification in a KVO-compliant way, you should use one
of the following techniques:
a) [self insertObject:in<Key>AtIndex:]
b) [self removeObjectFrom<Key>AtIndex:]
c) [self replaceObjectIn<Key>AtIndex:withObject:]
d) Mutate the result of [self mutableArrayValueForKey:] rather than
directly mutating the array.
e)
[self willChange:valuesAtIndexes:forKey:]
// mutate the array directly
[self didChange:valuesAtIndexes:forKey:]
f) Replace the array whole with [self set<Key>:] or [self
setValue:forKey:]
-Ken -
Ty i will try that and post the result back =)
I did use this one* to notify the Controller of changes, maybe it will also
work for changing just values =).
*
* "Mutate the result of [self mutableArrayValueForKey:] rather than
directly mutating the array."
*
On Jan 30, 2008 8:07 AM, Ken Thomases <ken...> wrote:
> On Jan 29, 2008, at 6:16 PM, Miguel Coxo wrote:
>
>> Hello, so i have one ArrayController that is bound to one Array, and a
>> tablecolumn that is bound to the ArrayController objects (not any
>> particular
>> value).
>>
>> As a normal behavior the controller gets notified when i add or remove
>> objects, but i have a thread that every second updates the objects.
>> What is
>> the correct way to notify the Controller that a specific object
>> values where
>> changed?
>>
>> I'm guessing the Thread shouldn't have direct access to the
>> Controller since
>> its in a "lower" abstraction layer, so how do i notify or make the
>> controller track changes to values?
>>
>> The column is not bound to values because it has custom dataCells
>> that need
>> several properties from the array objects.
>
> If you modify the array in one of the KVO-compliant ways, then the
> array controller will be informed automatically. However, you should
> not do so from a background thread, because the notification will be
> delivered on whatever thread does the modification, and bindings will
> attempt to update the GUI from the background thread, which will cause
> trouble.
>
> You can use performSelectorInMainThread:... to have the background
> thread push the modification to the main thread. You may not need to
> use a thread at all. Will an NSTimer meet your needs?
>
> To perform the modification in a KVO-compliant way, you should use one
> of the following techniques:
>
> a) [self insertObject:in<Key>AtIndex:]
>
> b) [self removeObjectFrom<Key>AtIndex:]
>
> c) [self replaceObjectIn<Key>AtIndex:withObject:]
>
> d) Mutate the result of [self mutableArrayValueForKey:] rather than
> directly mutating the array.
>
> e)
> [self willChange:valuesAtIndexes:forKey:]
> // mutate the array directly
> [self didChange:valuesAtIndexes:forKey:]
>
> f) Replace the array whole with [self set<Key>:] or [self
> setValue:forKey:]
>
>
> -Ken
>
--
Cumprimentos, Miguel Coxo. -
On Jan 30, 2008, at 3:16 PM, Miguel Coxo wrote:
> On Jan 30, 2008 8:07 AM, Ken Thomases <ken...> wrote:
> On Jan 29, 2008, at 6:16 PM, Miguel Coxo wrote:
>
>> Hello, so i have one ArrayController that is bound to one Array,
> and a
>> tablecolumn that is bound to the ArrayController objects (not any
>> particular
>> value).
>>
>> As a normal behavior the controller gets notified when i add or
> remove
>> objects, but i have a thread that every second updates the objects.
>> What is
>> the correct way to notify the Controller that a specific object
>> values where
>> changed?
>
> Ty i will try that and post the result back =)
> I did use this one* to notify the Controller of changes, maybe it
> will also work for changing just values =).
>
> * "Mutate the result of [self mutableArrayValueForKey:] rather than
> directly mutating the array."
Ah, I see what you were getting at. You're changing properties of the
objects in the array, and you need the controller to "notice" those
changes even though it's not bound to those properties. Sorry, I
didn't understand that part of your original question.
In an earlier thread I argued for a different approach to another
reader:
http://lists.apple.com/archives/cocoa-dev/2007/Dec/msg01329.html
I hope that helps.
Cheers,
Ken -
Well for further reference what i ended up doing was:
- Created a bogus Property "cellData" that is a function returning self
- The updated thread just used the pair willChange and didChange "cellData"
and it works
I tried the other way with the keyPathsForValuesAffectingValueForKey method,
but he wasn't called (Im using RubyCocoa might be the reason =).
On Jan 31, 2008 12:41 AM, Ken Thomases <ken...> wrote:
> On Jan 30, 2008, at 3:16 PM, Miguel Coxo wrote:
>
>> On Jan 30, 2008 8:07 AM, Ken Thomases <ken...> wrote:
>> On Jan 29, 2008, at 6:16 PM, Miguel Coxo wrote:
>>
>>> Hello, so i have one ArrayController that is bound to one Array,
>> and a
>>> tablecolumn that is bound to the ArrayController objects (not any
>>> particular
>>> value).
>>>
>>> As a normal behavior the controller gets notified when i add or
>> remove
>>> objects, but i have a thread that every second updates the objects.
>>> What is
>>> the correct way to notify the Controller that a specific object
>>> values where
>>> changed?
>>
>> Ty i will try that and post the result back =)
>> I did use this one* to notify the Controller of changes, maybe it
>> will also work for changing just values =).
>>
>> * "Mutate the result of [self mutableArrayValueForKey:] rather than
>> directly mutating the array."
>
>
>
> Ah, I see what you were getting at. You're changing properties of the
> objects in the array, and you need the controller to "notice" those
> changes even though it's not bound to those properties. Sorry, I
> didn't understand that part of your original question.
>
> In an earlier thread I argued for a different approach to another
> reader:
>
> http://lists.apple.com/archives/cocoa-dev/2007/Dec/msg01329.html
>
> I hope that helps.
>
> Cheers,
> Ken
>
>
--
Cumprimentos, Miguel Coxo.



