Accessing unknown getter

Discussion in 'iOS Programming' started by ArtOfWarfare, Nov 27, 2009.

  1. ArtOfWarfare macrumors G3


    Nov 26, 2007
    Properties continue to confuse me to no end...

    I have a view controller which contains the properties username and password (both NSStrings.)

    @interface UserTableController : UITableViewController <ComposeViewControllerDelegate>
    	NSArray *users;
    	NSOperationQueue *infoQueue;
    	NSMutableArray *userInfoArray;
    	NSMutableArray *spinnerArray;
    	NSString *username;
    	NSString *password;
    - (void) loadInfo:(NSString *)i;
    - (void) compose;
    @property (readwrite, assign) NSString *username;
    @property (readwrite, assign) NSString *password;
    These are both synthesized in the main...

    @synthesize username;
    @synthesize password;
    and then set in the initWithStyle

    self.username = @"ArtOfWarfare";
    self.password = @"***";
    Later on, a module view controller is added to the initial view controller.

    ComposeViewController *composeViewController = [[ComposeViewController alloc] init];
    composeViewController.delegate = self;
    [self presentModalViewController:composeViewController animated: YES];
    [composeViewController release];
    I would like this modual view controller to display the username and password, but it wasn't working. So I commented out the lines telling it to do that and instead have a simple NSLog to make sure it gets the username and password. Here's that code:

    NSLog (@"I say the username is %@ and the password is %@.", self.delegate.username, self.delegate.password);
    This gets me the error: accessing unknown 'password' getter method

    I don't understand. The delegate of composeViewController is userTableController, shouldn't self.delegate.password just grab the password then? I'm either using delegates or properties (or both) incorrectly... I still don't understand either of them particularly well and I tend to just copy and paste example code for them without understanding why.

    *** The actual code has the actual password in it... I'm not copying it down for obvious security reasons.
  2. robbieduncan Moderator emeritus


    Jul 24, 2002
    Your design is not really the correct way to do this: you should not be holding your model in your controller layer.
  3. firewood macrumors 604

    Jul 29, 2003
    Silicon Valley
    Religious nonsense. This has nothing to do with the OP's problem. You can hold state information anywhere, M, V, C, or global, if you don't care about reuse (which wasn't part of the OP's problem).

    To debug, try switching from dot to bracket notation for your messaging, and breaking the access into multiple statements using temporary variables you can watch in the debugger.
  4. North Bronson macrumors 6502

    Oct 31, 2007
    San José
    Think of a protocol as an agreement. My delegate promises to hold up that agreement, but anything else is out the window.

    There's no real reason that your ComposeViewController should "know" that your UserTableController has the "username" and "password" properties without explicitly making those part of the protocol. In fact, to code your ComposeViewController with the assumption that your delegate will always be a UserTableController is starting to run counter of one of the principles of delegation; the code becomes reusable because different objects can assume the delegation role -- "locking in" the delegate to be a UserTableController loses this benefit.

    I would add these following lines to your ComposeViewController protocol:

    - (NSString *)passwordForComposeViewController:(ComposeViewController *)controller;
    - (NSString *)usernameForComposeViewController:(ComposeViewController *)controller;
    Then, in your UserTableController (along with the other methods of the ComposeViewController protocol):

    - (NSString *)passwordForComposeViewController:(ComposeViewController *)controller
        NSString *string = [self password];
        return string;
    - (NSString *)usernameForComposeViewController:(ComposeViewController *)controller
        NSString *string = [self username];
        return string;
    Then, in your ComposeViewController, you should be able to:

    NSString *username = [[self delegate] usernameForComposeViewController: self];
    NSString *password = [[self delegate] passwordForComposeViewController: self];
    NSLog(@"Username: %@, username);
    NSLog(@"Password: %@, password);
    This might seem like more work, but I think this runs more in line with the spirit of delegation. Also, take a good look at the delegation section in "Cocoa Design Patterns" in your documentation.

Share This Page