Resolved Remotely accessing an instance variable

Discussion in 'iOS Programming' started by multinode, May 27, 2011.

  1. multinode, May 27, 2011
    Last edited: May 27, 2011

    macrumors regular

    Joined:
    Feb 4, 2011
    #1
    "nextPath" is an instance variable in OrderEntryAppDelegate. It's value in the start method in OrderEntryAppDelegate.m is "/Subjects". However, when it's used in SubjectsController.m, it's value is nil. Why? What did I do wrong please?

    Code:
    
    [B]OrderEntryAppDelegate.h[/B]
    
    #import <UIKit/UIKit.h>
    #import "SubjectsController.h"
    
    @interface OrderEntryAppDelegate : NSObject <UIApplicationDelegate> {
    	UIWindow *window;
    	UIViewController *welcomeController;
    	SubjectsController *subjectsController;
    	UINavigationController *navigationController;
    	NSString *pathToHere, *nextPath;
    	UIButton *startButton;
    	}
    -(IBAction) start:(id)sender;
    
    @property (nonatomic, retain) IBOutlet UIButton *startButton;
    @property (nonatomic, retain) IBOutlet UIWindow *window;
    @property (nonatomic, retain) IBOutlet UIViewController *welcomeController;
    @property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
    @property (nonatomic, retain) NSString *pathToHere, *nextPath;
    
    @end
    
    [B]OrderEntryAppDelegate.m[/B]
    
    #import "OrderEntryAppDelegate.h"
    #import "SubjectsController.h"
    #import "UIKit/UIKit.h"
    
    @implementation OrderEntryAppDelegate
    
    @synthesize window;
    @synthesize welcomeController;
    @synthesize startButton;
    @synthesize navigationController;
    @synthesize pathToHere;
    @synthesize nextPath;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
    	(NSDictionary *)launchOptions {
    
    	pathToHere = @"/";
    
    	//activate the start button
    	[startButton setHidden:NO];
    
    	//create navigation controller
    	navigationController = 
    		[[UINavigationControlleralloc] initWithRootViewController: welcomeController];
     	[self.window addSubview:navigationController.view];
    	[self.window makeKeyAndVisible];
    
    	return YES;
    	}
    
    
    -(void) start:(id)sender{
    	//create myTableViewController instance
    	subjectsController = [[SubjectsController alloc] initWithStyle:UITableViewStylePlain];
    	nextPath = [pathToHere stringByAppendingPathComponent:@"Subjects"];
    	[navigationController pushViewController:subjectsController animated:YES];
    	printf("The start button was tapped\n");
    	}
    
    								
    - (void)dealloc {
    	[window release];
    	[super dealloc];
    	}
    @end
    
    
    [B]SubjectsController.h[/B]
    
    #import <UIKit/UIKit.h>
    #import "OrderEntryAppDelegate.h"
    
    @interface SubjectsController : UITableViewController {
    	NSString *pathToHere;
    	NSArray *dataArray;
    	}
    
    @property (nonatomic, retain) NSString *pathToHere
    @property (nonatomic, retain) NSArray *dataArray;
    @end
    
    [B]SubjectsController.m[/B]
    
    #import "OrderEntryAppDelegate.h"
    #import "SubjectsController.h"
    
    @implementation SubjectsController
    
    @synthesize pathToHere;
    @synthesize dataArray;
    
    - (id)initWithStyle:(UITableViewStyle)style {
    	self = [super initWithStyle:style];
    	if (self) {
    		// Custom initialization.
    		self.title = @"Conference Subjects";		
    		}
    	return self;
    	}
    
    -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    	OrderEntryAppDelegate *delegate = [[UIApplication sharedApplication]delegate];
    	NSError *error = nil;
    	self.pathToHere = [delegate nextPath];
    	dataArray = [[NSFileManager alloc] contentsOfDirectoryAtPath:delegate.pathToHere 
    		error:&error];
    	return [dataArray count];
    	}
    
    
    -(UITableViewCell *) tableView:tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    	OrderEntryAppDelegate *delegate = [[UIApplication sharedApplication]delegate];
    	NSError *error = nil;
    	self.pathToHere = [delegate nextPath];
    	dataArray = [[NSFileManager alloc] contentsOfDirectoryAtPath:delegate.pathToHere 
    		error:&error];
    	UITableViewCell *cell = 
    		[self.subjectsViewdequeueReusableCellWithIdentifier:@"UITableViewCell"];
    	if (!cell) {
    		cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
    			reuseIdentifier:@"UITableViewCell"] autorelease];
    		}
    	cell.textLabel.text = [dataArray objectAtIndex:indexPath.row];
    	return cell;
    	}
    
    
    /*-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    	OrderEntryAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    	UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    	delegate.nextPath = [pathToHere stringByAppendingPathComponent:selectedCell.textLabel.text];
    	conferencesController = [[ConferencesController alloc] initWithStyle:UITableViewStylePlain];
    	[delegate.navigationController pushViewController:conferencesController animated:YES];
    	printf("next Level\n");
    	}*/
    @end
    
    
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    I've not read all your code but this is the first thing that jumps out at me:

    You are not using your synthesized accessor to set nextPath.

    Code:
    nextPath = [pathToHere stringByAppendingPathComponent:@"Subjects"];
    
    is not the same as (or even remotely similar to)

    Code:
    self.nextPath = [pathToHere stringByAppendingPathComponent:@"Subjects"];
    
    In the first case you directly set the variable to point to an autoreleased object. You should expect that this will get released at the end of the current run loop. This is what is happening and therefore is the expected behaviour.

    In the second case you use some syntactic sugar to call the setter method. This setter method will (due to your property declaration and synthesize call) retain the object and the set the pointer. So the object will not get released at the end of the current run loop.

    The lesson to take out of this is never directly set properties. Always use the accessor methods via self. or calling setXXX directly. This is also why it's a good idea to give the variable a different name to the property (convention is to call the variable _propertyName) and use the synthesize directive to make that work. This prevents you making this error.
     
  3. thread starter macrumors regular

    Joined:
    Feb 4, 2011
    #3
    Thanx Robbie. Your correction fixed all my problems. Hours and hours and hours of thinking and thinking and thinking.
     

Share This Page