Notification when changes occur to an array?

  • Hi everyone,

    This is my first post here, so be easy on me. I've searched the
    archives and Google without success, so now I ask you for your expert
    input.

    The problem; I have an NSArrayController with a corresponding
    NSArray. I would like some of my other classes to react to changes to
    the array, at least when it changes size.

    I've read the class reference for both the controller and the array,
    but I cannot seem to find any built in notification support for the
    array as a whole (like when an element is added, a "sizeHasChanged"
    notification should be sent).

    I could manually check the size of my array at each instance in my
    program where it's needed, but that breaks the notification idea.

    Thanks in advance.
    / Mattias
  • It sounds like you don't want a notification really.  Use Key Value
    Observing instead.  That will tell you when an item is added or
    removed from the array, and even what the new/old objects are.

    Alternatively, you could subclass NSArrayController to issue a
    notification, but this seems messier.

    Mike.

    On 26 Sep 2006, at 15:07, Mattias Arrelid wrote:

    > Hi everyone,
    >
    > This is my first post here, so be easy on me. I've searched the
    > archives and Google without success, so now I ask you for your
    > expert input.
    >
    > The problem; I have an NSArrayController with a corresponding
    > NSArray. I would like some of my other classes to react to changes
    > to the array, at least when it changes size.
    >
    > I've read the class reference for both the controller and the
    > array, but I cannot seem to find any built in notification support
    > for the array as a whole (like when an element is added, a
    > "sizeHasChanged" notification should be sent).
    >
    > I could manually check the size of my array at each instance in my
    > program where it's needed, but that breaks the notification idea.
    >
    > Thanks in advance.
    > / Mattias
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/mike.abdullah%
    > 40gmail.com
    >
    > This email sent to <mike.abdullah...>
  • > It sounds like you don't want a notification really.  Use Key Value
    > Observing instead.  That will tell you when an item is added or
    > removed from the array, and even what the new/old objects are.

    KVO seems more appropriate, I agree on that! Thanks for pointing me
    in the right direction.

    I'm still having some difficulties grasping how I'm supposed to get
    it working though. I have a simple class with an NSMutableArray,
    called "spotlights". If I want to observe changes to it's count, I
    assume I'm supposed to have the following two methods in my class
    (the class that contains the array):

    - (void)registerObservers
    {
    [spotlights addObserver: self
        forKeyPath: @"count"
                     options: NSKeyValueObservingOptionNew
                     context: NULL];
    }

    - (void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                            change:(NSDictionary *)change
                            context:(void *)context
    {

        if ([keyPath isEqual:@"count"]) {
      NSLog(@"The count did change.");
        }
    }

    Btw, I call "registerObservers" in my init method of my class.

    When running the example, the application exits due to SIGNAL 5
    (SIGTRAP). This is what follows:

    2006-09-27 15:36:35.835 Prototype[4163] An uncaught exception was raised
    2006-09-27 15:36:35.835 Prototype[4163] [<NSCFArray 0x350f00>
    addObserver:forKeyPath:options:context:] is not supported. Key path:
    count
    2006-09-27 15:36:35.835 Prototype[4163] *** Uncaught exception:
    <NSInvalidArgumentException> [<NSCFArray 0x350f00>
    addObserver:forKeyPath:options:context:] is not supported. Key path:
    count

    This sounds like the NSMutableArray isn't completely KVO? Like there
    is no method for setting a new count? Or am I wrong? *confused*

    Thanks on advance
    / Mattias
  • as someone else has pointed out Key-Value Observing is the proper
    technique for this.

    Have a look at the KVO doc, and also the first item in the Cocoa
    Bindings troubleshooting doc.  That lists a common gotcha (not adding
    items to the array in a KVO/KVC compliant manner)

    On Sep 26, 2006, at 10:07 AM, Mattias Arrelid wrote:

    > Hi everyone,
    >
    > This is my first post here, so be easy on me. I've searched the
    > archives and Google without success, so now I ask you for your
    > expert input.
    >
    > The problem; I have an NSArrayController with a corresponding
    > NSArray. I would like some of my other classes to react to changes
    > to the array, at least when it changes size.
    >
    > I've read the class reference for both the controller and the array,
    > but I cannot seem to find any built in notification support for the
    > array as a whole (like when an element is added, a "sizeHasChanged"
    > notification should be sent).
    >
    > I could manually check the size of my array at each instance in my
    > program where it's needed, but that breaks the notification idea.
    >
  • The method registerObservers must be declared like this:

    [spotlights addObserver:self forKeyPath:@"@count"
    options:NSKeyValueObservingOptionNew context:NULL];

    Because the key is @count, not count by itself.

    Julio Cesar Silva dos Santos
    <j.c.s.s...>
    Blogjective-C
    http://www.jcs.santos.nom.br/wp
    FetchYourLyrics
    http://www.jcs.santos.nom.br/fyl/fyl.html

    On 27/09/2006, at 10:43, Mattias Arrelid wrote:

    >> It sounds like you don't want a notification really.  Use Key
    >> Value Observing instead.  That will tell you when an item is added
    >> or removed from the array, and even what the new/old objects are.
    >
    > KVO seems more appropriate, I agree on that! Thanks for pointing me
    > in the right direction.
    >
    > I'm still having some difficulties grasping how I'm supposed to get
    > it working though. I have a simple class with an NSMutableArray,
    > called "spotlights". If I want to observe changes to it's count, I
    > assume I'm supposed to have the following two methods in my class
    > (the class that contains the array):
    >
    > - (void)registerObservers
    > {
    > [spotlights addObserver: self
    > forKeyPath: @"count"
    > options: NSKeyValueObservingOptionNew
    > context: NULL];
    > }
    >
    > - (void)observeValueForKeyPath:(NSString *)keyPath
    > ofObject:(id)object
    > change:(NSDictionary *)change
    > context:(void *)context
    > {
    >
    > if ([keyPath isEqual:@"count"]) {
    > NSLog(@"The count did change.");
    > }
    > }
    >
    > Btw, I call "registerObservers" in my init method of my class.
    >
    > When running the example, the application exits due to SIGNAL 5
    > (SIGTRAP). This is what follows:
    >
    > 2006-09-27 15:36:35.835 Prototype[4163] An uncaught exception was
    > raised
    > 2006-09-27 15:36:35.835 Prototype[4163] [<NSCFArray 0x350f00>
    > addObserver:forKeyPath:options:context:] is not supported. Key
    > path: count
    > 2006-09-27 15:36:35.835 Prototype[4163] *** Uncaught exception:
    > <NSInvalidArgumentException> [<NSCFArray 0x350f00>
    > addObserver:forKeyPath:options:context:] is not supported. Key
    > path: count
    >
    > This sounds like the NSMutableArray isn't completely KVO? Like
    > there is no method for setting a new count? Or am I wrong? *confused*
    >
    > Thanks on advance
    > / Mattias
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/j.c.s.s%
    > 40brturbo.com.br
    >
    > This email sent to <j.c.s.s...>
  • > This sounds like the NSMutableArray isn't completely KVO? Like
    > there is no method for setting a new count? Or am I wrong? *confused*

    No, NSMutableArray is fully KVO, but count is not part of that, and
    you shouldn't use it in the way you're proposing. There is no method
    to set a new count, because it's just a derived property.

    It's not clear to me what you're trying to do, but arrays don't
    magically acquire new elements, so why don't you use the method that
    actually adds the object to the array to handle whatever you're
    trying to handle? You'll just have to write a method that calls the
    array controller's method addObject: and have your user interface
    call that method instead of the addObject: method.

    Good luck!
    Hank
  • >> This sounds like the NSMutableArray isn't completely KVO? Like
    >> there is no method for setting a new count? Or am I wrong? *confused*
    >
    > No, NSMutableArray is fully KVO, but count is not part of that, and
    > you shouldn't use it in the way you're proposing. There is no
    > method to set a new count, because it's just a derived property.

    Ok, I was thinking something like that... Thanks for making things a
    bit more clear.

    > It's not clear to me what you're trying to do, but arrays don't
    > magically acquire new elements, so why don't you use the method
    > that actually adds the object to the array to handle whatever
    > you're trying to handle? You'll just have to write a method that
    > calls the array controller's method addObject: and have your user
    > interface call that method instead of the addObject: method.

    Well, I've been told - in this very thread - that KVO actually CAN
    help me achieve what I want here. I'd rather not create a new method
    that takes care of interface elements (I have lots of arrays and
    buttons etc.). But maybe it's not possible without to much hassle in
    this case.

    Regards / Mattias
previous month september 2006 next month
MTWTFSS
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
Go to today