Ошибка приложения iPhone - PullRequest
0 голосов
/ 19 июля 2011

Смирись со мной на этом.

У меня есть приложение для iPhone. Это анкета-заявка. Есть несколько типов вопросов, некоторые имеют ползунок, некоторые имеют текстовый ввод и т. Д. Я разработал контроллер представления для каждого типа вопроса.

Два примера типов контроллеров вопросов: TextInputQuestionViewController и SliderQuestionViewController.

У меня есть rootViewcontroller с именем QuestionnaireViewController. Это определяется следующим образом:

#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;
    SliderQuestionViewController* currQ; //need to create a generic var
    TextInputQuestionViewController* currQ;
    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, retain) SliderQuestionViewController* currQ;
@property(nonatomic, retain) TextInputQuestionViewController* currTI;
@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



#import "QuestionnaireViewController.h"
#import "dbConnector.h"
#import "ASIHTTPRequest.h"
#import "JSONKit.h";
#import "Answer.h";


@implementation QuestionnaireViewController
@synthesize questions, questionArray, db, currQ, currQNum, answerArray, qaTitle, secId, delegate;

-(void)viewDidLoad{
    [self initialise];
    answerArray = [[NSMutableArray alloc]init];
    [super viewDidLoad];
    self.title = qaTitle; //set to whatever section is
}

-(void) initialise {
    currQNum = 0;
    [self loadQuestions];
    UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Start" style:UIBarButtonItemStylePlain target:self action:@selector(switchViews:)];          
    self.navigationItem.rightBarButtonItem = anotherButton;
}

-(void) loadQuestions {
    db = [[dbConnector alloc]init];
    //code to initialise view
    [db getQuestions:secId from:@"http://dev.speechlink.co.uk/David/get_questions.php" respondToDelegate:self]; 
}

//called when questions finished loading
//stores dictionary of questions
- (void)requestFinished:(ASIHTTPRequest *)request
{
    NSData *responseData = [request responseData];
    NSString *json = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    NSDictionary *qs = [json objectFromJSONString]; 
    self.questions = qs;
    [json release]; 
    [qs release];
    [self setQuestions];
}


//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

        }
        //if else to create appropriate view controller - NEED to identify question type

        [question setQuestionId:[q objectForKey:@"questionId"] withTitle:[q objectForKey:@"question"] number:[q objectForKey:@"questionNumber"] section:[q objectForKey:@"sectionId"] questionType: [q objectForKey:@"type"]];
        /* Add it to question (mutable) array */
        [questionArray addObject:question]; 
        [question release];
    }
}

-(void) startQuestion:(NSInteger)index isLast:(BOOL)last{
    //currQ = [[QuestionViewController alloc]init];
    currQ = [questionArray objectAtIndex:index];
    //push currQ onto navigationcontroller stack
    [self.navigationController pushViewController:currQ animated:YES];
    [currQ addButton:self isLast: last];
}

//pushes new view onto navigation controller stack
-(void) switchViews:(id)sender{ 
    Answer* ans = currQ.question.answer;
    ans.questionId = currQ.question.qId;
    ans.entryId = @"1";//temporary;
    if(currQNum < [questionArray count] - 1){       
        if(currQNum > 0){           
            //if else for different input types
            NSString* qt = currQ.question.qType;
            if([qt isEqualToString:@"Slider"]){
                ans.answer = currQ.sliderLabel.text;
            }else if([qt isEqualToString:@"Option"]){               

            }else if([qt isEqualToString:@"TextInput"]){
                //NSLog(@"%@", currQ.inputAnswer);
                ans.answer = currQ.inputAnswer.text;
            }else if([qt isEqualToString:@"ImagePicker"]){

            }else{

            }                       
            [answerArray addObject: ans];
            [ans release];
        }
        [self startQuestion:currQNum isLast:FALSE];     
        currQNum++;
    }else{
        ans.answer = currQ.sliderLabel.text;
        [answerArray addObject: ans];

        //store data temporarily - section finished     
        [self startQuestion:currQNum isLast:TRUE];              
        currQNum++;
    }
    [ans release];
}

-(void) finishQuestionnaire:(id)sender{
    //go back to main manual
    //if else statement for answers
    NSString* answ = currQ.sliderLabel.text;
    [answerArray addObject: answ];
    [delegate finishedSection:answerArray section:secId];
    [answ release];
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.questions = nil;
    self.currQ = nil;
    [super viewDidUnload];
}

//hide back button in navigation bar
- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = YES;
}

- (void)dealloc {
    [currQ release];
    [db release];
    [questionArray release];
    [questions release];
    [super dealloc];
}

@end

проблемные строки с указанным выше находятся в функции switchViews. Мне нужно сделать ответ равным конкретному компоненту ввода в этом виде вопроса (значение слайдера, значение ввода текста). Поэтому мне нужно сделать currQ типом, который может быть создан с использованием любого контроллера представления.

Поэтому мне нужна общая переменная для хранения текущего вопроса. currQ содержит текущий вопрос, но в данный момент имеет тип SliderQuestionViewController. Я попытался изменить это на id, но он выдает нагрузку «Запрос для члена ... не структура объединения», а также груз ошибочно назначенных указателей.

Дайте мне знать, если вам нужно больше кода.

Ответы [ 2 ]

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

Если вы ищете «универсальную» переменную, вы можете использовать id.Убедитесь, что вы не определили тип как id*, звездочка должна , а не .

Однако, лучшая идея - создать суперкласс для ваших контроллеров представления вопросов.Создайте суперкласс с именем QuestionViewController, который наследуется от UIViewController, а Slider и TextInput (и любые другие) наследуют от QuestionViewController.Затем вы можете определить свою переменную следующим образом: QuestionViewController* currQ; Вы также можете включить в этот суперкласс любую обычную функциональность и устранить дублирование.

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

Это выглядит так, как будто вы хотите указатель для UIViewController, так что просто используйте его как тип.Затем вы можете привести его к тому подклассу, который вам понравится позже.Например:

-(void)myAction:(UIViewController *)vc {
    SpecialViewController *svc = (SpecialViewController *)vc;
    ...
}

В вашем случае объявите

UIViewController* currQ;

и затем приведите его по мере необходимости в реализации, чтобы получить доступ к различным свойствам и методам ваших двух подклассов.

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