views:

2872

answers:

5

I'm trying to figure out the SQLite functionality for the iPhone, and I'm having some problems reading my database file from an overridden UITableViewDataSource function. I am storing the database file location in an ivar (as an NSString) in my application delegate, however when I try to access that string from an overridden UITableViewDataSource function, it returns some other object. If I access the string from any of the classes own instance methods, it works fine.

Is there any way to access the application delegate from within overridden UITableViewDataSource functions?

+4  A: 

The Application is a singleton which maintains a reference to the app delegate. You can always access your app delegate using:

[UIApplication sharedApplication].delegate

You may need to cast the return to your own app delegate class to get rid of warnings.

Roger Nolan
A: 

The problem turned out to be really simple. I had created the NSString to hold the path to my database file using stringByAppendingPathComponent: . I failed to realize that this was going to be autoreleased, and so I didn't bother to explicitly retain it. That reason it was returning a different type of object was because that memory had been reused once the string had been autoreleased.

Explicitly retaining the string holding the path to the database file solved the problem.

jammur
+4  A: 

Roger is correct, but I personally find it extremely confusing to mix dot syntax and bracket syntax in the same statement.

If this confuses you as well, the equivalent syntax, using only bracket notation, is:

[[UIApplication sharedApplication] delegate];

and yes, you may need to cast the result to be your application delegate class, rather than the generic UIApplicationDelegate class, or you will get a number of compiler warnings, most likely.

mmc
+1  A: 

While I don't like sticking too much into my AppDelegate, I'll often need to access it to get to other singletons in my app, which makes the method call + cast a little cumbersome. So in most of my apps, I'll define a quick macro in my global header file.

Example follows:


#define MY_DELEGATE (AppDelegate*)[[UIApplication sharedApplication] delegate]

It's a lot easier to refer to MY_DELEGATE.

Justin Searls
That's pretty useful. But my eyes start to bleed when I see people prefixing things by "My". I can't imagine who else might own it…Also, I'm not sure why you'd need `AppDelegate` to access singletons. A singleton is accessed like `[[MyHowdyClass sharedHowdyer] someMethod]`. No `AppDelegate` required.
Jonathan Sterling
(1) If it saves any face, I also despise "My" in identifiers. For the sake of illustration I wrote "MY" to replace my app's initials--mine actually reads "QM_DELEGATE". Your "MyHowdyClass" did this too ;) (2) You're absolutely right that (design pattern) singletons should be accessed directly--I was over-simplifying; I should have said "shared instance" or something to denote a third-party class of which my entire app will make use of just a single instance. Not itself a singleton, but not always worth wrapping into one. Having it on the AppDelegate for easy access is handy in this case.
Justin Searls
Haha… Got it. [extra text to get SO to let me leave a comment]
Jonathan Sterling
A: 

UITableViewDataSource does not use functions. It is an Objective-C protocol which prototypes methods, which are implemented in whichever class implements UITableViewDataSource.

See my answer here for a discussion of the difference between functions and methods (both are useful, but in different contexts).

Jonathan Sterling