开发者

Help with iphone application - Issue with class property referencing

I don't have a clue why this error is showing. I have the following class:

#import <Foundation/Foundation.h>
#import "Answer.h"

@interface Question : NSObject {
    NSString* qId;
    NSString* qTitle;
    NSString* qNumber;  
    NSString* sectionId;
    NSString* qType;
    Answer* answer;
}

@property (nonatomic, retain) NSString* qId;
@property (nonatomic, retain) NSString* qTitle;
@property (nonatomic, retain) NSString* qNumber;
@property (nonatomic, retain) NSString* sectionId;
@property (nonatomic, retain) NSString* qType;
@property (nonatomic, retain) Answer* answer;

#import "Question.h"

@implementation Question
@synthesize qId, qTitle, qNumber, sectionId, qType, answer;

-(id)init
{
    if (self = [super init])
    {
        // Initialization code here
        answer = [[Answer alloc]init];
    }
    return self;
}

-(void) dealloc{
    [answer release];
    [super dealloc];
}

@end

I have a property of type Question in the following class:

#import <Foundation/Foundation.h>
#import "TextInputQuestion.h"

@interface TextInputQuestionViewController : UIViewController {
    Question *question;
    IBOutlet UILabel *questionTitle;
    IBOutlet UILabel *inputLabel;
    IBOutlet UITextField *inputAnswer;
}

@property (nonatomic, retain) UILabel *questionTitle;
@property (nonatomic, retain) UILabel *inputLabel;
@property (nonatomic, retain) Question *question;
@property (nonatomic, retain) UITextField *inputAnswer;

- (void) addButton:(id)sender isLast:(BOOL)last;
- (void) setQuestionId:(NSString*)quId withTitle:(NSString*)quTitle number:(NSString*)quNum section:(NSString*)sId questionType:(NSString*)qt;

@end

I synthesize Question* question in the .m file.

In my QuestionnaireVieController class:

#import <UIKit/UIKit.h>
#import "JSONKit.h";
#import "dbConnector.h"
#import "SliderQuestionViewController.h";
#import "TextInputQuestionViewController.h";
#import "MainMenuProtocol.h";

@interface QuestionnaireViewController : UIViewController {
    NSDictionary* questions;
    NSMutableArray* questionArray;
    NSMutableArray* answerArray;
    dbConnector* db;
    NSInteger currQNum; 
    NSString* qaTitle;
    NSString* secId;
    id<MainMenuProtocol>delegate;
}

@property(nonatomic, retain) NSDictionary* questions;   
@property(nonatomic, retain) NSMutableArray* questionArray;
@property(nonatomic, retain) NSMutableArray* answerArray;
@property(nonatomic, retain) dbConnector* db;
@property(nonatomic) NSInteger currQNum;
@property(nonatomic, retain) NSString* qaTitle;
@property(nonatomic, retain) NSString* secId;
@property(nonatomic, retain) id <MainMenuProtocol> delegate;

-(void) setQuestions;
-(void) startQuestion:(NSInteger)index isLast:(BOOL)last;
-(void) loadQuestions;
-(void) initialise;
-(void) finishQuestionnaire:(id)sender;
-(void) switchViews:(id)sender;

@end

I use the following method in the .m file to populate the questionArray with different types of viewcontroller:

//assigns JSON to question objects
-(void) setQuestions {
    questionArray = [[NSMutableArray alloc] init];
    for (NSDictionary *q in self.questions) {               
        /* Create Question object and populate it */

        id question;
        if([[q objectForKey:@"type"] isEqualToString:@"Slider"]){
            question = [[SliderQuestionViewController alloc]init];              
            //set min max values
        }else if([[q objectForKey:@"type"] isEqualToString:@"Option"]){

        }else if([[q objectForKey:@"type"] isEqualToString:@"TextInput"]){
            question = [[TextInputQuestionViewController alloc]init];                  开发者_StackOverflow社区     
        }else if([[q objectForKey:@"type"] isEqualToString:@"ImagePicker"]){

        }else{
            //comments          
        }
        [questionArray addObject:question];
        [question setQuestionId:[q objectForKey:@"questionId"] withTitle:[q objectForKey:@"question"] number:[q objectForKey:@"questionNumber"] section:[q objectForKey:@"sectionId"] questionType: [q objectForKey:@"type"]];
        [question release];

    }
}

When I do the following in the above .m file:

NSLog(@"%@", [questionArray objectAtIndex:0]);

I get:

<TextInputQuestionViewController: 0x6062e90>

When I try to do:

NSLog(@"%@", [questionArray objectAtIndex:0].question);

I get an error:

request for member 'question' in something not a structure or union

Why on earth can it not access the question variable? Especially when it actually logs my controller object. am I missing something here...


You're running into the madness that is dot-notation. Switch it to this, and I bet it works (or at least you get a useful error):

NSLog(@"%@", [[questionArray objectAtIndex:0] question]);

Dot-notation is a slapped-on addition in ObjC2, and the compiler still can't always figure it out, especially when you're trying to pass a message to an id (like objectAtIndex: returns). The compiler gets confused, thinks this this is the dot you use for a struct rather than a message in disguise, and bails.


EDIT

foo.bar = baz;
=> [foo setBar:baz];

foo.bar.baz
=> [[foo bar] baz];

This, btw, is actual Objective-C. Dot-notation is just a sloppy way of writing this. In particular, it's important to understand that foo.bar=baz is exactly "send the message setBar: to foo." The default behavior for that is to assign a property using the declared setter semantics, but that's just the default. You can override setBar: to do anything. You can even reconfigure the message dispatch system to not call the method setBar: (this is not an obscure feature, it's used by Core Data and Core Animation). Objective-C is a dynamic language, and unfortunately dot-notation tends to muddy this by making it look like Java.


if you just need to reference the Question object, then you can define a class QuestionViewController for example that contains the Question object and inherits this class in both SliderQuestionViewController and TextInputQuestionViewController and when you want to get an object out of the array you can downcast it to an object of type QuestionViewController:

Question * q = ((QuestionViewController *)[questionArray objectAtIndex:0]).question;
q.id = qId;
NSLog(@"%@", q.qId);

or you can simply write:

Question * q = (Question*)[[questionArray objectAtIndex:0] question];
q.id = qId;
NSLog(@"%@", q.qId);


Have you included Question.h in your view controller?

i.e.

#include "Question.h"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜