views:

164

answers:

3

This is a very newbie question, and this is something I have done many times before, but there's something I'm missing this time.

In my AppDelegate.h file I declare an NSArray and set it as a property:

@interface AppDelegate : NSObject {
NSArray *lines;

}

@property(readwrite, retain) NSArray *lines;
@end

And then in the AppDelegate.m file in the awakeFromNib method I alloc it:

lines = [[NSArray alloc] init];

Then I have a method that sets the lines array:

NSString *fileContents = [NSString stringWithContentsOfFile:[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/sometextfile.txt"] encoding:NSUTF8StringEncoding error:NULL];
lines = [fileContents componentsSeparatedByString:@"\n"];

I have an array controller thats bound to "AppDelegate.self.lines" then I have a table column bound to "Array Controller.arrangedObjects". I can confirm that the array is being updated (tested using NSLog) however the contents of the table are not being update (it remains blank).

Is there something obvious I'm missing here?

+2  A: 

When you say you have a arrangedObjects bound to the column do you mean you set the tablview datasource? If not you to set the tableview datasource to the lines array

ennuikiller
OK, I have an Array Controller whose Content Array is set to AppDelegate.self.lines. Then I bind the Array Controller's arrangedObjects to the table column. I haven't set a dataSource for t, do I need to?
macatomy
ennuikiller: Bindings are an alternative to data sources.
Peter Hosey
A: 

You might want to read through this, it's got some good diagrams and explanations. What ennuikiller is saying is correct, I think it's a problem with your datasource. This is done by calling

[aTable setDelegate:aDelegate];
slf
I tried setting the datasource/delegate to both the main app delegate and the array controller, neither worked.
macatomy
+2  A: 

You don't need a data source if you're using Bindings. One or the other.

I have an array controller thats bound to "AppDelegate.self.lines" …

Why self?

@property(readwrite, retain) NSArray *lines;

No, use copy here. Otherwise, you'll find yourself retaining someone else's mutable array, which they will then mutate. Then “your” array will have changed without you knowing it.

Then I have a method that sets the lines array:

lines = [fileContents componentsSeparatedByString:@"\n"];

This is why the table doesn't show anything. You're not going through the property, you're accessing the instance variable directly. Direct instance variable accesses do not cause KVO notifications, so the array controller never finds out about the change.

Even worse, you're leaking the old array (since you simply assign over it without releasing it) and under-retaining this new array. The new array is autoreleased, and you didn't retain it, so that instance variable will hold a dead object shortly. The automatic retaining is done by the setLines: method, which only gets called when you call it.

You need to go through the property:

self.lines = [fileContents componentsSeparatedByString:@"\n"];

A property access is an implicit accessor message, so this both retains the array (or copies it, once you correct the @property as I suggested above) and posts KVO notifications.

Peter Hosey
Thanks a ton Peter, that worked perfectly :)
macatomy