views:

340

answers:

3

I'm trying to access an NSMutableArray which is a data member of my AppDelegate class. It is synthesized in the implementation, and is an array of a custom class which has a "name" NSString data member.

I currently use it to fill a Table View (a SubView) like this:

cell.textLabel.text = [[[delegate contentArray] objectAtIndex:indexPath.row] name];

This works, but I get a warning:

warning: no '-contentArray' method found

It won't compile as:

cell.textLabel.text = [[delegate.contentArray objectAtIndex:indexPath.row] name];

I get this in that case:

error: request for member 'contentArray' in something not a structure or union

What is the proper way to access an array in the delegate?

Update: To declare delegate, in the table view controller header file, I include @class MainAppDelegate; and in the @interface I declare a data member MainAppDelegate *delegate;. In the table view controller's @implementation I do @synthesize delegate;.

A: 

You wil have to cast the delegate to the correct type. Like this:

cell.textLabel.text = [[[(MyAppDelegate*) delegate contentArray]
    objectAtIndex:indexPath.row] name]
St3fan
+1  A: 

I think I solved it. The MainAppDelegate.h header file was not imported into the table view controller's .m file. I guess it doesn't make sense to me to have both the main AppDelegate.h file and the table view's ViewController.h file both importing each other.

mike_b
It's not that big of a deal. The MainAppDelegate needs to know about the ViewController, and the ViewController needs to know about the MainAppDelegate.Kind of a convoluted circular dependency, but that's the beauty of #import.
alesplin
+1  A: 

To declare delegate, in the table view controller header file, I include @class MainAppDelegate; and in the @interface I declare a[n instance variable] MainAppDelegate *delegate;. In the table view controller's @implementation I do @synthesize delegate;.

So you have forward-declared the class name MainAppDelegate and used it to declare an instance variable. Since you are @synthesizing a property, I assume you declared one of those, too.

I currently use it to fill a Table View (a SubView) like this:

cell.textLabel.text = [[[delegate contentArray] objectAtIndex:indexPath.row] name];

This works, but I get a warning:

warning: no '-contentArray' method found

It won't compile as:

cell.textLabel.text = [[delegate.contentArray objectAtIndex:indexPath.row] name];

I get this in that case:

error: request for member 'contentArray' in something not a structure or union

That's because the compiler doesn't know what methods or properties delegate has. You've declared the name of its class, but the compiler doesn't know anything else about it, because you haven't provided an @interface for that class.

The solution is to #import the header file for the delegate class into the table view controller class's implementation file, probably immediately after #importing the table view controller class's own header.

Also, I suspect that the array more properly belongs to the table view controller than to the app delegate, but I don't know enough about Cocoa Touch to say for sure.

Peter Hosey
This helps me understand *why* the header file missing caused problems. I'm more used to C/C++ in which an undeclared class via #import would just cause errors, not warnings. As for where the contentArray is located, its my understanding that the best place for that data is in the AppDelegate because that way multiple views can access the data at once via the AppDelegate. Every example I've seen does this. I'm sure there are other ways.
mike_b
You would have gotten an error in Objective-C, too, if you had not forward-declared the class name with `@class`. With that declaration (which is proper to have in the header of a class that uses the declared class), the compiler knows at least that this is the name of a class; it just doesn't know anything else about that class until you give it an `@interface` for it.
Peter Hosey