views:

193

answers:

3

I am having a very odd issue retrieving/retaining a variable in my iPhone application delegate (AppDelegate). Initially, I can step through and see that my values are passed to logfile (the NSString variable in question), but when logfile is retrieved from another class (see the code below), it faults.

Here is my AppDelegate.h file:

   #import < UIKit/UIKit.h >

@interface AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *_window;

 MainViewController *_mainViewController;
 NSString *logFile;
}

@property (nonatomic, retain) NSString *logFile;
@property (nonatomic, retain) ProductClass *item;
@property (nonatomic, retain) UIWindow *window;

-(void)appendToLog:(NSString *)textToLog;
@end

Here is my AppDelegate.m:

#import "AppDelegate.h"
#import "MainViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize logFile;

- (void) applicationDidFinishLaunching:(UIApplication *)application {    
 _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

 _mainViewController = [[MainViewController alloc] init];
 UINavigationController *_navigationController = [[UINavigationController alloc] initWithRootViewController:_mainViewController];

 //Initialize the product class
     [self appendToLog:@"Application loaded"];

     [_window addSubview:_navigationController.view];
     [_window makeKeyAndVisible];
}

-(void)appendToLog:(NSString *)textToLog {
 //Append the log string
 if(logFile!=nil) {
  NSString *tmp = [[logFile stringByAppendingString:textToLog] stringByAppendingString:@"\n"];
  logFile = tmp;
 }
 else {
  NSString *tmp = [textToLog stringByAppendingString:@"\n"];
  logFile = tmp;
 }
}

@end

When I use the call (from another class):

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *s = [appDelegate logFile];

"logfile" comes back as "out of scope" so the local variable "s" is mush.

What am I doing wrong here? It isn't making sense to me.

+2  A: 

You should replace logFile = tmp; with self.logFile = tmp; because you need to use the "self." prefix when assigning an ivar in order for the code to call the proper settor method. As it is, you're just assigning the ivar to an autoreleased object instance, instead of retaining it. The "self." prefix ensure that the code does the right thing. Without it, you're just assigning the variable without retaining it.

lucius
This is still giving me the same incorrect behavior (app doesn't crash, just doesn't return any values).
Brett
UPDATE: I cleaned and rebuilt after including self.logfile and now it works great! Thanks!
Brett
A: 

From the UIApplication class reference - UIApplication assigns and does not retain the delegate. You need to initialize your instance of AppDelegate first.

BojanG
@lucius has the right solution. You shouldn't be initializing your app delegate anywhere, you always want to get the pointer to your app delegate through `UIApplication`. Let the system worry about initializing and retaining for you.
kubi
A: 

I would recommend prefixing logfile with self in your assignment statements in your AppDelegate. For example, self.logfile = ...

Jason McCreary