Binding NSTextField to NSString

I have a very simple question I hope someone can answer as I start understanding bindings. I want to programmatically change my NSString value and have the NSTextField update to that value thru bindings. I have a NSTextField and NSLabel. To represent the value of the myString properly changing I have a NSButton.

  • I have NSTextField's Value bound to myString property of App Delegate with Continuously Update Value checked.
  • I have NSLabel's Value bound to myString Property of App Delegate.
  • I have NSButton outlet hooked to setDefault method.
  • When I type in NSTextField the NSLabel updates as expected but when I click the button the myString property is updated but not in the NSTextField.

    What do I need to do to get the NSTextField update to the myString property????

    AppDelegate.h

    @interface AppDelegate : NSObject<NSApplicationDelegate>
    {
       NSString *myString;
    }
    
    @property (assign) IBOutlet NSWindow *window;
    @property NSString *myString;
    
    - (IBAction)setDefault:(id)sender;
    @end
    

    AppDelegate.m

    @implementation AppDelegate
    
    @synthesize window = _window;
    @synthesize myString;
    
    - (void)applicationDidFinishLaunching:(NSNotification*)aNotification
    {
       myString = @"This is a string";
    }
    
    - (IBAction)setDefault:(id)sender
    {
       NSLog(@"%@", myString);
       myString = @"This is a string";
       NSLog(@"%@", myString);
    }
    @end
    

    It shouldn't be

    myString = @"This is a string";
    

    but this:

    self.myString = @"This is a string";
    

    both in -applicationDidFinishLaunching: and in -setDefault: . Don't forget to specify self in your NSLog statements as well. You'd probably like to specify a different string in -setDefault: so that you can actually see that a change is taking place.

    One other thing: You're effectively saying that you want to assign to myString, but that's not appropriate for an object. Instead of:

    @property NSString *myString;
    

    you should instead use

    @property (copy) NSString *myString;
    

    or at least

    @property (retain) NSString *myString;
    

    The former is preferred because passing a NSMutableString instance effectively copies it as a NSString , while passing a NSString instance simply retains it.

    Good luck to you in your endeavors.


    I recommend that you prefix your member variables. This way you can distinguish between setting the member directly or using the setter . In your example I would do the following.

    @interface AppDelegate : NSObject<NSApplicationDelegate>
    {
       NSString *m_myString;
    }
    
    @property (assign) IBOutlet NSWindow *window;
    @property NSString *myString;
    
    - (IBAction)setDefault:(id)sender;
    @end
    

    ...

    @implementation AppDelegate
    
    @synthesize window = _window;
    @synthesize myString = m_myString;
    
    - (void)applicationDidFinishLaunching:(NSNotification*)aNotification
    {
       self.myString = @"This is a string";
    }
    
    - (IBAction)setDefault:(id)sender
    {
       NSLog(@"%@", m_myString);
       self.myString = @"This is a string";
       NSLog(@"%@", m_myString);
    }
    @end
    

    Notice, that I changed the @synthesize to assign the member variable.

    To clarify:

    self.myString = @"This is a string";
    

    .. is an alternative syntax for ...

    [self setMyString:@"This is a string"];
    

    You can also set the member directly ...

    [self willChangeValueForKey:@"myString"];
    m_myString = @"This is a string";
    [self didChangeValueForKey:@"myString"];
    

    But then you need to "inform" observers of the binding as illustrated above.

    链接地址: http://www.djcxy.com/p/85244.html

    上一篇: 我怎样才能使一个NSTextField焦点重绘本身?

    下一篇: 将NSTextField绑定到NSString