Learn Objective-C on the Mac - Mark Dalrymple [46]
Note that for the swornEnemy combo box and the primaryMotivation radio button matrix, which had somewhat complicated procedures for setting their values, retrieving the values from them is simple enough to easily fit on a single line.
The remaining complex view, the powers checkbox matrix, is also a bit more complicated to retrieve values from, since we have to find all the checked boxes and get their associated strings. This should do the trick:
Compile and run the app, click around in the powers matrix, and you should see the output log update accordingly.
Finally, we need to implement a method to retrieve the value from the notes view, an instance of NSTextView. NSTextView provides a lot of delegate methods that allow us to do many different things in response to the user’s actions while editing the text. We will take a very simple approach, grabbing a copy of the value each time the user edits the text, which means after every single keypress! This would be an extreme thing to do for a large document view, where we might have performance consequences to consider, but for a smaller text view intended to hold a few notes, we shouldn’t encounter any trouble with this simple approach:
You may notice one unusual thing happening here: We’re creating a copy of the result we get from notesView’s string method. The reason for this is that internally, an NSTextView hangs onto a string of its own for editing and display, and its string method actually returns a pointer to that internal string object. If we don’t make a copy we’re going to end up with that string being referenced directly by our villain, which can lead to confusion later on, when we are switching between different villains being displayed by these GUI objects. We’d end up assigning the same string to several villains, and editing any villain’s notes would simultaneously edit all of them! NSTextField doesn’t cause us these sorts of problems, since its stringValue method already gives us a copy instead of passing along its internal string object.
One other thing to point out is that the NSTextView delegate method that we implemented has a curious method signature, and we are passed an NSNotification as a parameter. Here you’re seeing a bit of the generic notification system that is part of Cocoa. Using a class called NSNotificationCenter, it’s possible to configure any object to receive notifications from any other object when certain events occur. When you set up a delegate for an NSTextView (just to name an example; this pattern occurs for some other classes as well), some of the delegate methods you can choose to implement are specific to the delegate and can only be implemented there, but some of them are these kind of notification methods that can, in principle, also be implemented in any other class that has access to the NSTextView and is set up to receive notifications from it. You’ll see more about this topic later in the book.
In Conclusion
We’ve covered a lot of material in this chapter. You’ve learned some of the basics that are vital to any Cocoa application: how to execute your own initialization code when your app launches; how to use Interface Builder to lay out views in a window, including specifying resizing behavior; the basics of using a variety of Cocoa’s GUI classes; and more. In the next chapter we’re going to build on what we’ve done so far, extending the VillainTracker application to be able to handle an array of villains listed in a table.
Chapter 5
Using Table Views
In Chapter 4, you learned a bit about some of Cocoa’s most common GUI components, from buttons and simple input fields to full-fledged text editors. We haven’t yet talked about one of Cocoa’s biggest, most complex view classes, NSTableView. In this chapter, you’ll learn how to use an NSTableView to