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

jamesapp

macrumors 6502a
Original poster
Mar 7, 2008
544
0
working on Cocoa Programming for Mac OS X Third Edition
by Aaron Hillegass
i am on the RaiseMan application
i was able to get undo working, but when i went to compile undo of edits i got a
few errors when i compiled. I believe my errors are in my MyDocument.m file
because it was the only file i changed from my last build.
i got six errors and 8 warnings my errors are:
error: 'insertObject' undeclared (first use in this function)
error: syntax error before ':' token
i believe these errors came from

Code:
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index

error 'p' undeclared (first use in this function)
and this error i beleive came from
Code:
[self startObservingPerson:p];



i will include my MyDocument.m file:


Code:
#import "MyDocument.h"
#import "Person.h"

@implementation MyDocument

- (void)changeKeyPath:(NSString *)keyPath
ofObject:(id)obj
toValue:(id)newValue
{
	//setValue:forKeyPath: will cause the key-value observing method
	//to be called, which takes care of the undo stuff
	[obj setValue:newValue forKeyPath:keyPath];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
	NSUndoManager *undo = [self undoManager];
	id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
	
	//NSNull objects are used to represent nil in a dictionary
	if (oldValue == [NSNull null]) {
		oldValue = nil;
	}
	NSLog(@"oldValue = %@", oldValue);
	[[undo prepareWithInvocationTarget:self] changeKeyPath:keyPath
	                                              ofObject:object
												   toValue:oldValue];
	[undo setActionName:@"Edit"];
}

- (void)startObservingPerson:(Person *)person
{
	[person addObserver:self
	         forKeyPath:@"personName"
	            options:NSKeyValueObservingOptionOld
	            context:NULL];
	
	[person addObserver:self
			 forKeyPath:@"expectedRaise"
	            options:NSKeyValueObservingOptionOld
	            context:NULL];
}

- (void)stopObservingPerson:(Person *)person
{
	[person removeObserver:self forKeyPath:@"personName"];
	[person removeObserver:self forKeyPath:@"expectedRaise"];
}

- (id)init
{
	[super init];
	employees = [[NSMutableArray alloc] init];
	return self;
}

- (void)dealloc
{
	[self setEmployees:nil];
	[super dealloc];
}

- (void)setEmployees:(NSMutableArray *)a
{
	//this is an unusual setter method. we are going to add a lot
	// of smarts to it in the next chapter.
	if (a==employees)
		return;
	
	for (Person *person in employees) {
		[self stopObservingPerson:person];
	}
	
	[a retain];
	[employees release];
	employees = a;
	
	for (Person *person in employees) {
		[self startObservingPerson:person];
}

- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
	NSLog(@"adding %@ to %@", p, employees);
	//add the inverse of this operation to the undo stack
	NSUndoManager *undo = [self undoManager];
	[[undo prepareWithInvocationTarget:self]
	 removeObjectFromEmployeesAtIndex:index];
	if (![undo isUndoing]){
		[undo setActionName:@"Insert Person"];
	}
	//Add the Person to the array
	[self startObservingPerson:p];
	[employees insertObject:p atIndex:index];
}

//- (id)init
//{
  //  self = [super init];
    //if (self) {
    
        // Add your subclass-specific initialization here.
        // If an error occurs here, send a [self release] message and return nil.
    
    //}
    //return self;
//}

- (NSString *)windowNibName
{
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @"MyDocument";
}

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];
    // Add any code here that needs to be executed once the windowController has loaded the document's window.
}

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
    // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.

    // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.

    // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.

    if ( outError != NULL ) {
		*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
	}
	return nil;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
    // Insert code here to read your document from the given data of the specified type.  If the given outError != NULL, ensure that you set *outError when returning NO.

    // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. 
    
    // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
    
    if ( outError != NULL ) {
		*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
	}
    return YES;
}

//- (void)inserObject:(Person *)p inEmployeesAtIndex:(int)index
//{
//	NSLog(@"adding %@ to %@", p, employees);
	// Add the inverse of this operation to the undo stack
//	NSUndoManager *undo = [self undoManager];
//	[[undo prepareWithInvocationTarget:self]
//	 removeObjectFromEmployeesAtIndex:index];
//	if (![undo isUndoing]) {
//		[undo setActionName:@"Insert Person"];
//	}
	//Add the Person to the Array
//	[employees insertObject:p atIndex:index];
//}

- (void)removeObjectFromEmployeesAtIndex:(int)index
{
	Person *p = [employees objectAtIndex:index];
	NSLog(@"removing %@ from %@", p, employees);
	//Add the inverse of this operation to the undo stack
	NSUndoManager *undo = [self undoManager];
	[[undo prepareWithInvocationTarget:self]insertObject:p
									  inEmployeesAtIndex:index];
	if (![undo isUndoing]) {
		[undo setActionName:@"Delete Person"];
	}
	[self stopObservingPerson:p];
	[employees removeObjectAtIndex:index];
}

@end

does anyone have this program from the book working
i can give more information if needed.
any help would be appreciated.
 

MrFusion

macrumors 6502a
Jun 8, 2005
613
0
West-Europe
working on Cocoa Programming for Mac OS X Third Edition
by Aaron Hillegass
i am on the RaiseMan application
i was able to get undo working, but when i went to compile undo of edits i got a
few errors when i compiled. I believe my errors are in my MyDocument.m file
because it was the only file i changed from my last build.
i got six errors and 8 warnings my errors are:
error: 'insertObject' undeclared (first use in this function)
error: syntax error before ':' token
i believe these errors came from

Code:
	for (Person *person in employees) {
		[self startObservingPerson:person];
has no closing }. So the } of the function is used to close the for loop.

When you see such an error: syntax error before ':' token
You should always check if everything is closed off properly. Does every line in your header have an ;, does every function have { and }, and so on.
If you fix this, all your other errors will most likely also go away. But you also could get a bunch of new ones.
 

jamesapp

macrumors 6502a
Original poster
Mar 7, 2008
544
0
thanks for the reply and short
lesson. I was looking in Xcode
at the line where it indicated
there was an error. And the error
was like you showed me, a couple
of lines up. I got the program
to work anyway, thanks again.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.