Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7414093
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T07:00:17+00:00 2026-05-29T07:00:17+00:00

I have a view MyView , and it has images which I want to

  • 0

I have a view MyView, and it has images which I want to bind with an array in my AppDelegate.

MyView class

@interface MyView : NSView {
@private
    NSArray *images;
}

@end

+ (void)initialize
{
    [self exposeBinding:@"images"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"Changed!");
}

My AppDelegate

@property (retain) NSArray *images;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{   
    images = [[NSMutableArray alloc] init];

    [view bind:@"images" toObject:self withKeyPath:@"images" options:nil];
    // [self addObserver:view forKeyPath:@"images" options:0 context:nil]; // !!!

    MyImage *img = [[MyImage alloc] ...];

    [self willChangeValueForKey:@"images"];
    [[self images] addObject:img];
    [self didChangeValueForKey:@"images"];
    [img release];
}

Without [self addObserver:view forKeyPath:@"images" options:0 context:nil]; the method observeValueForKeyPath: is never called.

Is it necessary to call addObserver: when using bind:? Does bind: set the KVO? And why doesn’t binding work?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T07:00:18+00:00Added an answer on May 29, 2026 at 7:00 am

    What you need is an implemented setter for the images property like below. The most common use-case for this is that you need to invalidate the drawing and request redraw with
    -setNeedsDisplay:YES.

    - (void)setImages:(NSArray *)newImages
    {
      if(newImages != images) {
        [images release];
        images = newImages;
        [images retain];
      }
    
      [self setNeedsDisplay:YES]; // Addition and only difference to synthesized setter
    }
    

    You can drop the -exposeBinding: call, since that has only influence on plugins for Interface Builder, and those where lost with the introduction of Xcode 4.

    The reason why the -observeValueForKeyPath:ofObject:change:context: message is not send is that for a binding the observer is not the bound-to object. There is another object in the background. (In the stack form a breakpoint you can see that its class is NSEditableBinder.) So it is correct to register as observer from within the view to the view property @”images”.

    Another way to get notified about a change in the view is to override -setValue:forKey: method. Then you would need to check the key string and see if it was equal to @"images". But since there are other methods from the KVC protocol like -setValue:forKeyPath:, you would need to be extra careful to not disturb the machinery, i.e. always call super.

    Uh. I just realize that my answer so far assumes the easier case where you replace the whole array. Your question was for an array modification. (You do declare an immutable array property in your example, though, which only allows replacement. So keep it as declared, and my approach so far will work. Below I show the other alternative.)

    Ok, lets assume you do this in the app delegate, a replacement:

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {   
        [view bind:@"images" toObject:self withKeyPath:@"images" options:nil];
    
        MyImage *img = [[MyImage alloc] ...];
    
        self.images = [NSArray arrayWithObject:img];
        [img release];
    }
    

    You don’t need to post the change (using willChangeValueForKey: and didChangeValueForKey:, since you go through the declared property. They do that for you.

    Now to the other approach where you modify an array. For that you need to use a mutable array property and modify it through an KVO-notifying proxy, like this:

    [self mutableArrayValueForKey:@"images"] addObject:img];

    This would pick up the change on the sending (bound-to) side. Then it would be transported to the view through the binding machinery, and eventually set using KVC.

    There, on the receiving end in the view, you would need to pick up the property change to @”images”. That could be done by overwriting the collection accessor method(s) and do more work there, instead of just accepting the the change. But that is a bit complicated, since there are quite a few accessor methods (See docs). Or, simpler, you could add another observation relationship from within the view.

    For that, somewhere in initialization (-awakeFromNib: for example) of the view:

    [self addObserver:self forKeyPath:@"images" options:0 context:nil];
    

    and then:

    - (void)observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context
    {
      [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    
      if([keyPath isEqualToString:@"images"]) {
        [self setNeedsDisplay:YES]; // or what else you need to do then.
      }
    }
    

    Note that this last observer relationship has nothing to do with the binding any longer. The value change to the bound property properly arrives at the view without, you just don’t realize (get notified).

    That should work.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the problem that my view controller class has too many delegates and
I have this MVC view that has a list of images, these images are
In my View, which is a UserControl I have a ListView which has a
I have a content type that has 4 images to it. In my View
In my view model if have a: List<Car> where car has an Id and
Say I have a simple view, MyView . If I do: SELECT * FROM
the procedure: i have a script which uploads images (via hmtl-form and php) for
I have a Camera class that produces very large images at a high FPS
I have a custom UIView called TiledImage which has a single property named tiledImage
What I want to do I have a circular custom NSView subclass, and I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.