Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ehemmete

macrumors newbie
Original poster
Feb 12, 2010
4
0
I think this challenge is showing me that I am missing something fundamental about Cocoa/ObjC.

In MyDocument.m I have added another button to the alert sheet and that works correctly. Then I added an else if to alertEnded that is getting triggered correctly when I click my new button. I know that I need to set expectedRaise to 0, but I just don't know who to tell.

Following the delete option, I tried telling employeeController to setValue:0 forKey:mad:"expectedRaise". I've tried forKeyName:. I've tried the setNilValueForKey: method. I think that I want to use a keypath here, but I just can't reason out where to start and who to tell.

I think part of it is that I don't quite understand the delete statement. Why are we passing remove nil and what is remove actually doing.

Thanks! These forums have been very helpful up until now in my progress through the book.
 
Alright, here it goes. In MyDocument.m I have the IBAction for a Delete button that should remove the selected entries from an array shown in a tableView.
Code:
- (IBAction)removeEmployee:(id)sender
{
	NSArray *selectedPeople = [employeeController selectedObjects];
	NSAlert *alert = [NSAlert alertWithMessageText:@"Delete?"
						       defaultButton:@"Delete"
					  	    alternateButton:@"Cancel"
						         otherButton:@"Keep, but no raise"
				    informativeTextWithFormat:@"Do you really want to delete %d people?",
					  [selectedPeople count]];
	NSLog(@"Starting alert sheet");
	[alert beginSheetModalForWindow:[tableView window]
				  modalDelegate:self
				  didEndSelector:@selector(alertEnded:code:context:)
		 		       contextInfo:NULL];
}
When the user selects one of the buttons on the alert panel it will run the alertEnded:code:context method:
Code:
- (void)alertEnded:(NSAlert *)alert
			  code:(int)choice
		   context:(void *)v
{
	NSLog(@"Alert sheet ended");
	if (choice == NSAlertDefaultReturn) {
		[employeeController remove:nil];
	} else if (choice == NSAlertOtherReturn) {
		[employeeController setNilValueForKey:@"expectedRaise"];
	}
}
Here is where I am having the problem. I can get to the else if correctly, but I'm not sure who to send a message to at this point. The delete (which works) talks to employeeController, so I have been trying that. employeeController is defined in MyDocument.h:
Code:
	IBOutlet NSArrayController *employeeController;

When I run it as is and try to set the raise to 0, I get this error in the debugger:
Code:
[<NSArrayController 0x100443e50> setNilValueForKey]: could not set nil as the value for the key expectedRaise.
Which I think is telling me that it isn't using the method that I wrote in Person.m.
Code:
-(void)setNilValueForKey:(NSString *)key
{
	if ([key isEqual:@"expectedRaise"]) {
		[self setExpectedRaise:0.0];
	} else {
		[super setNilValueForKey:key];
	}
}

I feel like I should be able to use a key path to tell the elements in the array to set the expectedRaise value to 0, but I can't figure out how to get there.
 
The program is getting into the else if branch, but you're sending a setNilValueForKey to the employeeController. employeeController doesn't have an expectedRaise instance variable (ivar). So get the selected rows from the employeeController, which will return an NSArray with the selected instances of your Person class. You then need to create a loop which sets expected raise to zero in each instance.

crackpip
 
Thank you, thank you

That was enough to me push in the right direction (I think, at least it works now).
Code:
- (void)alertEnded:(NSAlert *)alert
			  code:(int)choice
		   context:(void *)v
{
	NSLog(@"Alert sheet ended");
	if (choice == NSAlertDefaultReturn) {
		[employeeController remove:nil];
	} else if (choice == NSAlertOtherReturn) {
		NSArray *selectedPeople = [employeeController selectedObjects];
		for (Person *p in selectedPeople)
		{
			[p setNilValueForKey:@"expectedRaise"];
		}
	}
}
 
Not sure why you need to call setNilValueForKey. Is there something I'm missing? I'm simply setting the value in the Person object, like so, which seems to work:

Code:
- (void) alertEnded: (NSAlert *) alert
               code: (int) choice
            context: (void *) vContext
{
    NSLog(@"Alert sheet ended");
    if (choice == NSAlertDefaultReturn)
    {
        [employeeController remove: nil];
    }
    else if (choice == NSAlertOtherReturn)
    {
        NSArray * employeesCollection = [employeeController selectedObjects];
        for (Person * employee in employeesCollection)
        {
            employee.expectedRaise = 0.0;
        }
    }
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.