2013-04-13 2 views
-1

У меня есть объект данных, который я хочу хранить, получать доступ и изменять по своему желанию между всеми различными представлениями приложения iOS. Ниже представлен базовый дизайн. Что интригует ко мне, так это то, что если я заменил NSMutableArray на NSString, все это работает, неважно, но в тот момент, когда я делаю его массивом и сохраняю в нем строку, он волнуется. Я выбрал массив, потому что мне нужно хранить разные версии userData в одно и то же время и в реальном приложении, есть намного больше, чем только одна переменная пользовательских данных.Почему я теряю свои объекты в NSMutableArray в функции prepareForSegue? Сбой

Я использую ARC, но я должен признать, что я не понимаю, правильно ли я использую его. Совет оценил.

// data.h 

@interface Data : NSObject 

@property (nonatomic, retain) NSMutableArray *data; 
@property (assign) NSNumber *Num; // determines which "level" on the array we're accessing 

+(id) sharedInstance; 

@end 



// data.m 

+(id) sharedInstance 
{  
    static id sharedInstance = nil; 
    if (sharedInstance == nil) { 
     sharedInstance = [[self alloc] init];   
    } 
    return sharedInstance; 
} 

- (id)init 
{ 
    self = [super init]; 

    if (self) 
    {   
     _Num = [NSNumber numberWithInt:0]; 
     _data = [NSMutableArray array]; 
    } 

    return self; 
} 

// userInput.h 

@property (strong, nonatomic) IBOutlet UITextField *userData; 

@property (nonatomic, retain) Data *dataStore; 

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

// userInput.m 

viewDidLoad 
{ 
    _dataStore = [Data sharedInstance]; 
      [_dataStore.data addObject:@""]; 

} 

prepareForSegue 
{ 
    int num = [_dataStore.Num intValue]; 

    NSString *transferData = [NSString stringWithFormat:@"%@", _userData.text]; 
    [_dataStore.data replaceObjectAtIndex:num withObject:transferData]; // crash at this line. replacing the empty string with whatever the user inputs 
} 

Отчет об ошибке

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 0 beyond bounds for empty array' 
+2

Почему вы заново изобретаете 'NSArray'? –

+1

Связано ли это с другим вопросом? Я посмотрел на ваш код там, и вы вызывали removeAllObjects на своих массивах, прежде чем пытались вызвать replaceObjectAtIndex: withObject :. Вы делаете то же самое здесь? – rdelmar

+1

Я согласен с rdelmar, что проблема лежит в другом месте. Однако в ответ на ваш вопрос, касающийся лучших практик ARC, я бы предложил вместо 'assign' использовать' strong', а не 'keep' и' weak'. Кроме того, почему вы хотите, чтобы 'Num' был' assign'/'weak'? Если вы хотите, чтобы ваш объект 'Data' сохранил его, вы, вероятно, хотите, чтобы это было« сильным ». – Rob

ответ

1

Порядок вашей прогрессии контроллера, как это:

ViewController ---> Начальное ---> TDC

Вы получаете общий экземпляр класса FlightData в методе viewDidLoad ViewController, а код init в этом классе создает все ваши массивы. Затем, когда вы готовитеForSegue для перехода к Initial, вы добавляете пустые строки к этим массивам. Он находится в следующем контроллере, Initial, где проблема. Вы вызываете removeAllObjects на тех массивах в файле didMoveToParentViewController, который появляется сразу после появления представления. Затем в prepareForSegue, чтобы перейти в TDC, вы пытаетесь использовать replaceObjectAtIndex: withObject: это, конечно, сбой приложения, поскольку вы просто опустошили эти массивы.

+0

Интересно. Я знаю, что это не часть исходного вопроса, но как я могу определить, когда представление «возвращается» к его родительскому представлению? Мне нужно уметь обнаруживать это в этом представлении, так как это означает, что Пользователь «отменяет» и хочет установить все значения в NIL. –

+0

Какой вид вы говорите? Я думаю, в общем, вы, вероятно, хотите использовать метод делегата, который вы можете отключить от кнопки отмены, чтобы отправить все, что вам нужно, чтобы вернуться к предыдущему контроллеру. Другим способом было бы использовать разматывание segue (если вы используете свою собственную кнопку, а не кнопку возврата по умолчанию). – rdelmar

+0

Initial -> ViewController Я использую кнопку возврата по умолчанию. Я изучу документы еще немного. –

Смежные вопросы