Cocoa Programming for Mac OS X - Aaron Hillegass [41]
NSLog(@"respondsToSelector:%@", methodName);
return [super respondsToSelector:aSelector];
}
You might want try adding this method to AppController.m now.
Challenge: Make a Delegate
Create a new application with one window. Make an object that is a delegate of the window. As the user resizes the window, make sure that the window always remains twice as tall as it is wide.
Here is the signature of the delegate method you will implement:
- (NSSize)windowWillResize:(NSWindow *)sender
toSize:(NSSize)frameSize;
The first argument is the window being resized. The second argument is a C struct that contains the size that the user has asked for:
typedef struct _NSSize {
float width;
float height;
} NSSize;
Here is how you create an NSSize that is 200 points wide and 100 points tall:
NSSize mySize = NSMakeSize(200.0, 100.0);
NSLog(@"mySize is %f wide and %f tall", mySize.width, mySize.height);
You can set the intial size of the window in the Size Inspector in Interface Builder.
Challenge: Make a Data Source
Make a to-do list application. The user will type tasks into the text field. When the user clicks the Add button, you will add the string to a mutable array, and the new task will appear at the end of the list (Figure 6.11).
Figure 6.11. Diagram of Challenge
When a new string is added to the array, you will need to send the message reloadData to the table view before you will see it.
You get extra points for making the table view editable. (Hint: NSMutableArray has a method replaceObjectAtIndex:withObject:)
Chapter 7. Key-Value Coding and Key-Value Observing
Key-value coding (or KVC) is a mechanism that allows you to set and get the value of a variable by its name. The name is just a string, but we refer to that name as a key. So, for example, imagine that you have a class called Student that has an instance variable called firstName of type NSString:
@interface Student : NSObject
{
NSString *firstName;
}
...
@ends
If you had an instance of Student, you could set its firstName like this:
Student *s = [[Student alloc] init];
[s setValue:@"Larry" forKey:@"firstName"];
You could read the value of its firstName like this:
NSString *x = [s valueForKey:@"firstName"];
The methods setValue:forKey: and valueForKey: are defined in NSObject. We know: This doesn’t look like rocket science, but it turns out that the ability to read and set a variable by its name is really powerful. The rest of this chapter will be a simple example that should illustrate some of that power.
Key-Value Coding
In Xcode, create a new project of type Cocoa Application. Name the project KvcFun and set the Class Prefix to KvcFun.
Open KvcFunAppDelegate.h, and add an instance variable called fido of type int:
@interface KvcFunAppDelegate : NSObject int fido; } @property (assign) IBOutlet NSWindow *window; @end In KvcFunAppDelegate.m, you are going to create an init method that sets and reads fido using key-value coding. This is a bit silly because it is going to be a long-winded way to get a simple result. This is designed to be illustrative rather than practical. What makes the method so long-winded is that the key-value coding methods work with objects, so instead of passing an int, you will need to create an NSNumber. Add this method to KvcFunAppDelegate.m: - (id)init { self = [super init]; if (self) { [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"]; NSNumber *n = [self valueForKey:@"fido"]; NSLog(@"fido = %@", n); } return self; } The key-value coding mechanism will automatically convert the NSNumber to an int before using it to set the value of fido. Build and run the application, but don’t expect much. When the blank window appears, fido = 5 will be logged to the console. If you have accessor methods for getting and setting fido, they will be used. You must, however, give them the correct names. The getter must be called fido and the setter