Hi
I'm new to Cocoa programming so apologise in advance that I'm likely to be missing something obvious. However, after several hours trying to fathom out a bug I'm completely stuck and would really appreciate some help!
I'm using XCode/Interface Builder 3 and Objective C 2.0 with garbage collection enabled. I have a Document-based application. In MyDocument.nib I have an NSTableView. This has its dataSource set to MyDocument in Interface Builder. I've implemented
- (NSInteger)numberOfRowsInTableViewNSTableView *)aTableView
and
- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn rowNSInteger)rowIndex
In my application, I don't want users to be able to edit the table view directly. I've not used an NSArrayController. The user clicks a button, a sheet slides down from where various options are set including the text to be displayed in the table view. This all works fine and the table view happily displays the text I want, including amendments carried out via my sheet. So far, so good.
The next thing for me to do, I thought to myself, was to implement saving. I have Aaron Hillegass' Cocoa book so implemented
- (BOOL)loadDataRepresentationNSData *)data ofTypeNSString *)aType
and
- (NSData *)dataRepresentationOfTypeNSString *)aType
rather than the alternatives offered by XCode 3 as I can't see how to use these (I've got Aaron's next edition on pre-order). However, I don't think that this is at the route of my problem.
Clicking Save in my application successfully creates a saved file and if I open this in TextEdit I can see the values I've entered (amongst some binary data, of course). When I try to Open a saved file the load appears to work; a fact I've tested as follows:
- (BOOL)loadDataRepresentationNSData *)data ofTypeNSString *)aType {
NSLog(@"Loading data of type %@", aType);
newArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if (newArray==nil) {
return NO;
} else {
NSLog(@"Loaded data");
[self setListOfGreetings:newArray];
// Debugging - let's see if my array has actually got anything in it
NSEnumerator *e = [listOfGreetings objectEnumerator];
greetingLister *import; // greetingLister is my model class
while (import = [e nextObject]) {
NSLog(@"%@", [import greeting]); // greeting is an NSString in my model class
}
NSLog(@"Size of loaded array %d", [newArray count]);
NSLog(@"Size of listOfGreetings %d", [listOfGreetings count]);
// greetingList is the tableview but sending reload/display messages doesn't work :-(
[greetingList reloadData];
[greetingList setNeedsDisplay:YES];
return YES;
}
}
For info, my numberOfRowsInTableView method shown in the output is:
- (NSInteger)numberOfRowsInTableViewNSTableView *)aTableView {
NSLog(@"tableView count %d", [listOfGreetings count]);
return [listOfGreetings count];
}
The output when I run my program and open a data file is:
[Session started at 2008-03-04 15:49:14 +0000.]
2008-03-04 15:49:14.865 TestApp[2457:10b] tableView count 0
2008-03-04 15:49:14.881 TestApp[2457:10b] tableView count 0
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x105d760, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x105cbd0, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x106e4a0, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x106edc0, has non-zero refcount = 1
2008-03-04 15:49:19.469 TestApp[2457:10b] Loading data of type DocumentType
2008-03-04 15:49:19.470 TestApp[2457:10b] Loaded data
2008-03-04 15:49:19.471 TestApp[2457:10b] This is some data from the saved file
2008-03-04 15:49:19.471 TestApp[2457:10b] Another entry from the saved file
2008-03-04 15:49:19.472 TestApp[2457:10b] Size of array 2
2008-03-04 15:49:19.472 TestApp[2457:10b] Size of listOfGreetings 2
2008-03-04 15:49:19.500 TestApp[2457:10b] tableView count 0
2008-03-04 15:49:19.510 TestApp[2457:10b] tableView count 0
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x1068330, has non-zero refcount = 1
However (and here's the rub) the table view doesn't update automatically. What appears to be happening is that the array (listOfGreetings) contains objects in the loadDataRepresentation method but as soon as this method ends, the array has no length at all. It's totally baffled me!?
I've tried turning off garbage collection and sending a retain message to newArray in loadDataRepresentation with no luck, but that was at the point that my clutching at straws reached frantic levels.
For info, listOfGreetings is an NSMutableArray declared as follows:
In MyDocument.h:
@property(copy) NSMutableArray *listOfGreetings;
In MyDocument.m:
@synthesize listOfGreetings;
This array contains objects that are my model class. The model class is set up using Objective C 2.0's properties. I don't think it's relevant as I'm writing and reading the data successfully, but I can post this code if need be.
I realise that I've kept great chunks of my code out of this post, but it's still pretty long as it is! If any more info is required I'll be happy to post it.
Thanks, in advance, for any tips!
I'm new to Cocoa programming so apologise in advance that I'm likely to be missing something obvious. However, after several hours trying to fathom out a bug I'm completely stuck and would really appreciate some help!
I'm using XCode/Interface Builder 3 and Objective C 2.0 with garbage collection enabled. I have a Document-based application. In MyDocument.nib I have an NSTableView. This has its dataSource set to MyDocument in Interface Builder. I've implemented
- (NSInteger)numberOfRowsInTableViewNSTableView *)aTableView
and
- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn rowNSInteger)rowIndex
In my application, I don't want users to be able to edit the table view directly. I've not used an NSArrayController. The user clicks a button, a sheet slides down from where various options are set including the text to be displayed in the table view. This all works fine and the table view happily displays the text I want, including amendments carried out via my sheet. So far, so good.
The next thing for me to do, I thought to myself, was to implement saving. I have Aaron Hillegass' Cocoa book so implemented
- (BOOL)loadDataRepresentationNSData *)data ofTypeNSString *)aType
and
- (NSData *)dataRepresentationOfTypeNSString *)aType
rather than the alternatives offered by XCode 3 as I can't see how to use these (I've got Aaron's next edition on pre-order). However, I don't think that this is at the route of my problem.
Clicking Save in my application successfully creates a saved file and if I open this in TextEdit I can see the values I've entered (amongst some binary data, of course). When I try to Open a saved file the load appears to work; a fact I've tested as follows:
- (BOOL)loadDataRepresentationNSData *)data ofTypeNSString *)aType {
NSLog(@"Loading data of type %@", aType);
newArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if (newArray==nil) {
return NO;
} else {
NSLog(@"Loaded data");
[self setListOfGreetings:newArray];
// Debugging - let's see if my array has actually got anything in it
NSEnumerator *e = [listOfGreetings objectEnumerator];
greetingLister *import; // greetingLister is my model class
while (import = [e nextObject]) {
NSLog(@"%@", [import greeting]); // greeting is an NSString in my model class
}
NSLog(@"Size of loaded array %d", [newArray count]);
NSLog(@"Size of listOfGreetings %d", [listOfGreetings count]);
// greetingList is the tableview but sending reload/display messages doesn't work :-(
[greetingList reloadData];
[greetingList setNeedsDisplay:YES];
return YES;
}
}
For info, my numberOfRowsInTableView method shown in the output is:
- (NSInteger)numberOfRowsInTableViewNSTableView *)aTableView {
NSLog(@"tableView count %d", [listOfGreetings count]);
return [listOfGreetings count];
}
The output when I run my program and open a data file is:
[Session started at 2008-03-04 15:49:14 +0000.]
2008-03-04 15:49:14.865 TestApp[2457:10b] tableView count 0
2008-03-04 15:49:14.881 TestApp[2457:10b] tableView count 0
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x105d760, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x105cbd0, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x106e4a0, has non-zero refcount = 1
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x106edc0, has non-zero refcount = 1
2008-03-04 15:49:19.469 TestApp[2457:10b] Loading data of type DocumentType
2008-03-04 15:49:19.470 TestApp[2457:10b] Loaded data
2008-03-04 15:49:19.471 TestApp[2457:10b] This is some data from the saved file
2008-03-04 15:49:19.471 TestApp[2457:10b] Another entry from the saved file
2008-03-04 15:49:19.472 TestApp[2457:10b] Size of array 2
2008-03-04 15:49:19.472 TestApp[2457:10b] Size of listOfGreetings 2
2008-03-04 15:49:19.500 TestApp[2457:10b] tableView count 0
2008-03-04 15:49:19.510 TestApp[2457:10b] tableView count 0
TestApp(2457,0xb0103000) malloc: free_garbage: garbage ptr = 0x1068330, has non-zero refcount = 1
However (and here's the rub) the table view doesn't update automatically. What appears to be happening is that the array (listOfGreetings) contains objects in the loadDataRepresentation method but as soon as this method ends, the array has no length at all. It's totally baffled me!?
I've tried turning off garbage collection and sending a retain message to newArray in loadDataRepresentation with no luck, but that was at the point that my clutching at straws reached frantic levels.
For info, listOfGreetings is an NSMutableArray declared as follows:
In MyDocument.h:
@property(copy) NSMutableArray *listOfGreetings;
In MyDocument.m:
@synthesize listOfGreetings;
This array contains objects that are my model class. The model class is set up using Objective C 2.0's properties. I don't think it's relevant as I'm writing and reading the data successfully, but I can post this code if need be.
I realise that I've kept great chunks of my code out of this post, but it's still pretty long as it is! If any more info is required I'll be happy to post it.
Thanks, in advance, for any tips!