PDA

View Full Version : Fundamental delegate question




ace2600
Mar 31, 2008, 12:19 AM
I know this is a basic delegate concept, and I should probably know the answer, but I do not.

I have a class as follows:
//TableController.h
@interface TableController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *myTableView;
//Array of strings
NSArray *arr;
}
@end//TableController.m
- (void)loadView {
myTableView.delegate = self;
myTableView.dataSource = self;
}
//Method for UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath withAvailableCell:(UITableViewCell *)availableCell {
//Want to access arr here
if([arr count]) {
}
}
Is there a way to access arr? I realize it belongs to TableController, but the delegate myTableView.delegate is set to self. If I cannot access arr directly, can I access indirectly (like through the invoker?) or somehow pass it to the delegate?



kainjow
Mar 31, 2008, 01:58 AM
You can access arr directly. It is an instance variable of the TableController class.

You are assigning the delegate to self. That means self must respond to certain methods. These methods are just normal methods in the class. Any method in the class can access ivars directly.

ace2600
Mar 31, 2008, 09:18 AM
Thanks Kainjow.

Okay, the problem appears to be when I access arr from the delegate methods (like cellForRowAtIndexPath), it gives me this error:
3/31/08 10:09:35 AM HomeFinder[1523] *** -[_UITableViewReorderingSupport count]: unrecognized selector sent to instance 0x355d20
3/31/08 10:09:35 AM HomeFinder[1523] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[_UITableViewReorderingSupport count]: unrecognized selector sent to instance 0x355d20' I can access arr just fine with the UITableViewDataSource methods like numberOfRowsInSection.

I have a feeling it's referencing the count for another variable (_UITableViewReorderingSupport) instead of arr, but not sure why.

kainjow
Mar 31, 2008, 09:19 AM
Sounds like a memory issue. Can you post the other code where you're creating arr?

ace2600
Mar 31, 2008, 09:58 AM
Thanks again Kainjow.

When initializing it with the convenience constructor arrayWithObjects, it fails, but using initWithObjects, it works.- (id)init
{
if (self = [super init])
{
// this title will appear in the navigation bar
self.title = @"Title";
}
//Causes error described earlier
//arr = [NSArray arrayWithObjects:@"first string", @"second string", nil];
//Works
arr = [[NSArray alloc] initWithObjects:@"test1", @"test2", nil];
return self;
}I'm rereading the memory management articles on apple, but still not sure why arr does not seem to be accessible when using arrayWithObjects.

Also, arr is defined in the header file exactly as described in the original post, NSArray *arr. No @property.

kainjow
Mar 31, 2008, 10:13 AM
arrayWithObjects returns an autoreleased object, whereas alloc/init does not. Autoreleased objects get released at another point in time and do not hang around.

So if you change your code to this it should work:

arr = [[NSArray arrayWithObjects:@"first string", @"second string", nil] retain];

Just make sure you release arr in your dealloc method.

ace2600
Mar 31, 2008, 10:48 AM
Thanks Kainjow!

Is there any difference/preference between:arr = [[NSArray arrayWithObjects:@"first string", @"second string", nil] retain];andarr = [[NSArray alloc] initWithObjects:@"first string", @"second string", nil];if I'm releasing both in dealloc?

And one last question on memory management.
if I had this:NSArray *subarr = [[NSArray arrayWithObjects:@"first string", @"second string", nil]
arr = [[NSArray arrayWithObjects:subarr, nil] retain];Would subarr be released when I release arr?

kainjow
Mar 31, 2008, 11:02 AM
Thanks Kainjow!

Is there any difference/preference between:arr = [[NSArray arrayWithObjects:@"first string", @"second string", nil] retain];andarr = [[NSArray alloc] initWithObjects:@"first string", @"second string", nil];if I'm releasing both in dealloc?

The only difference is with arrayWithObjects, you're retaining an autoreleased object, which kind of defeats the purpose (since you have the option of using one or the other). Think of it as like this:

arr = [[[[NSArray alloc] initWithObjects:@"first string", @"second string", nil] autorelease] retain];

And one last question on memory management.
if I had this:NSArray *subarr = [[NSArray arrayWithObjects:@"first string", @"second string", nil]
arr = [[NSArray arrayWithObjects:subarr, nil] retain];Would subarr be released when I release arr?

Yes. arr will retain subarr, and so when arr is released it releases all of its objects. If you retain subarr, before or after adding it to arr, you will need to release it yourself at some point.