+1  A: 

Instead of having a local copy of the variable just have these simple methods for setting and getting it when you need to. That way you get all the appends and edits from the view.

- (IBAction)appendString:(id)sender{
[[[textView textStorage] mutableString] appendString: string];

}

- (NSMutableString)getString{
return [[textView storage] mutableString];

}

Justin Meiners
That's an excellent solution, and I think I'm going to use it in my REAL program. However, I still want to figure this string binding junk out, as I expect it may be important later on, and at the very least, it pisses me off that it doesn't work the way I think it ought to.The thing that bothers me is that I can get floats and ints to bind just fine. It's objects such as NSString, etc, which are screwing with me, and I'm pretty sure it has something to do with the fact that they are all passed around by pointers.
TraxusIV
Yeah I bet in a lot of classes they make their own copy of the string so that way you can't ever get a direct pointer to it.
Justin Meiners
So you're going to store the model value in the view? Not very MVC; it's the controller that should own the model, and all views should get it from the controller.
Peter Hosey
With your fix, I will be doing it the correct way, now that I know how. :)
TraxusIV
+1  A: 

Inside my AppController class, I have declared an NSMutableString as a property.

This is the correct, MVC-compliant solution. The primary owner of the model should be the controller, not views. All views should obtain the model from the controller.

You should not, however, expose the string's mutability. Anything that uses the property may then attempt to mutate the string directly, without the AppController knowing about the change and being able to notify any observers of the property. The property should be declared as NSString, and as readwrite in order to provide an accessor with which to replace the value with a new string.

What I want to do is to set an initial value for the string, say @"First Entry\n", then, bind it to the NSTextView.

Set the value of the instance variable backing the property in init.

Bind the NSTextView in IB. Then, it will already be bound when you load the nib.

Note that you want to set the ivar before loading the nib. If you load the nib first, the text view will not see the change, because setting the ivar directly (as you should do in init, to avoid incurring property side-effects) is making the change behind the observer's (view's) back. If the change is already made when you load the nib (and the view starts observing), then there is nothing for the view to miss.

When I push the button, a method, -(IBAction)appendToString …

Every action in Cocoa takes exactly one argument—no more, no fewer. That argument is the control that sent the message. Thus, the correct signature is:

- (IBAction) appendToString:(id)sender;

… is called which appends @"Another Line\n" to the NSMutableString.

All you need to do is ask the property for your current string, make a mutable copy, make the change, and set the modified string as the new value of the property. Don't forget to release that mutable copy.

I want these changes to then be reflected in the NSTextView by means of bindings and key value observing, rather than by declaring an IBOutlet and manually updating the contents. I'd also like changes I make in the textview to edit the NSMutable string.

Both of these happen for free when you bind the text view's value binding to your AppController's property.

Peter Hosey