iOS - невозможно получить доступ к NSMutableArray в didSelectRowAtIndexPath? - PullRequest
0 голосов
/ 02 октября 2011

Я не могу получить доступ к своему NSMutableArray в didSelectRowAtIndexPath, хотя я могу получить к нему доступ в cellForRowAtIndexPath.

Вот мой код: -

- (void)viewDidLoad
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
    self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
    NSLog(@"%@", self.drinkArray);
    [super viewDidLoad];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    NSLog(@"I am inside cellForRowAtIndexPath");
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
    cell.textLabel.text = [dict objectForKey:@"name"]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    [dict release];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    DrinkDetails *detailViewController = [[DrinkDetails alloc] initWithNibName:@"DrinkDetails" bundle:nil];
    // ...
    // Pass the selected object to the new view controller.
    //detailViewController.drink = [self.drinkArray objectAtIndex:indexPath.row];

    NSLog(@"%@", self.drinkArray);

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];

}

Иногда NSLog печатаеткакой-то глупый вывод, и иногда он выдает мне ошибку «EXC_BAD_ACCESS».

Пожалуйста, посмотрите и проверьте, что не так с моим кодом.

Любая помощь будет оценена.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 02 октября 2011

У вас есть одна ( действительно две ) проблема, но главная проблема в вашем -cellForRowAtIndexPath: методе:

[dict release];

Избавьтесь от этой строки, и она должна работать нормально.

Причина, по которой это устраняет вашу проблему, заключается в том, что -objectAtIndex: просто возвращает указатель на запрошенный объект в памяти , поэтому вы не отправляете (и не должны) -releaseсообщение этому объекту, потому что NSArray получил право собственности на объект, когда он был вставлен.Отправка -release на эту ссылку на объект эффективно освобождает объект в памяти, и теперь этот индекс в NSArray указывает на мусорную память. BAD BAD BAD

Другая проблема заключается в том, что у вас есть утечка памяти здесь:

self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

Вы отправляете сообщение -retain на ссылку на объект, которую выуже есть право собственности путем отправки -alloc.(Это, конечно, предполагает, что ваш @property имеет модификатор установки retain)

Чтобы устранить эту проблему, просто отправьте сообщение -autorelease этому экземпляру:

self.drinkArray = [[[NSMutableArray alloc] initWithContentsOfFile:path] autorelease];
2 голосов
/ 02 октября 2011

Не выпускайте объект, если он не был создан с помощью alloc или получен методом, начинающимся с new или copy или явно retain 'ed. (NARC)

В этом случае:

NSDictionary * dict = [self.drinkArray objectAtIndex: indexPath.row];

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

По тому же признаку:

self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

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

self.drinkArray = [NSMutableArray arrayWithContentsOfFile:path];
1 голос
/ 02 октября 2011

Вы не должны [dict release] в cellForRowAtIndexPath. objectAtIndex не сохраняет его, поэтому он может быть удален из вашего массива при его освобождении.

...