Помощь с приложением iphone - проблема со ссылками на свойства класса - PullRequest
1 голос
/ 19 июля 2011

Понятия не имею, почему эта ошибка отображается.У меня есть следующий класс:

#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

У меня есть свойство типа Question в следующем классе:

#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

Я синтезирую Question* question в файле .m.

В моем классе QuestionnaireVieController:

#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

Я использую следующий метод в файле .m, чтобы заполнить QuestionArray различными типами 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];                       
        }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];

    }
}

Когда я делаюв приведенном выше файле .m:

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

Я получаю:

<TextInputQuestionViewController: 0x6062e90>

Когда я пытаюсь сделать:

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

Я получаю ошибку:

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

Почему он не может получить доступ к переменной вопроса?Особенно, когда это фактически регистрирует мой объект контроллера.я что-то здесь упускаю ...

Ответы [ 3 ]

0 голосов
/ 19 июля 2011

если вам просто нужно сослаться на объект Question, то вы можете определить класс QuestionViewController, например, который содержит объект Question и наследует этот класс как в SliderQuestionViewController и TextInputQuestionViewController, так и когда вы хотите получить объект из массива, вы можете уменьшить его до объекта типа QuestionViewController:

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

или вы можете просто написать:

Question * q = (Question*)[[questionArray objectAtIndex:0] question];
q.id = qId;
NSLog(@"%@", q.qId);
0 голосов
/ 19 июля 2011

Включили ли вы Question.h в свой контроллер вида?

т.е.

#include "Question.h"
0 голосов
/ 19 июля 2011

Вы сталкиваетесь с безумием, которое является точечной нотацией.Переключите его на это, и я уверен, что это сработает (или, по крайней мере, вы получите полезную ошибку):

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

Точечная нотация является добавленным дополнением в ObjC2, и компилятор все еще не всегда можетпонять это, особенно когда вы пытаетесь передать сообщение на id (например, objectAtIndex: return).Компилятор запутывается, думает, что это точка, которую вы используете для struct, а не скрытое сообщение, и освобождает под залог.


EDIT

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

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

Это, между прочим, фактическая цель-C.Точечная нотация - просто небрежный способ написания этого.В частности, важно понимать, что foo.bar=baz означает в точности «отправить сообщение setBar: на foo».Поведение по умолчанию для этого состоит в том, чтобы назначить свойство, используя объявленную семантику сеттера, но это только по умолчанию.Вы можете переопределить setBar:, чтобы сделать что-нибудь.Вы даже можете перенастроить систему рассылки сообщений, чтобы не вызывать метод setBar: (это не скрытая функция, она используется Core Data и Core Animation).Objective-C - это динамический язык, и, к сожалению, точечные обозначения имеют тенденцию запутывать его, делая его похожим на Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...