objectAtIndex - сообщение отправлено на освобожденный экземпляр - PullRequest
0 голосов
/ 01 марта 2011

У меня реальная проблема с поиском, где моя проблема в контроллере поиска. Это табличное представление с панелью поиска и контроллером отображения поиска. Раньше он работал нормально, но внезапно перестал работать. Я включил NSZombieEnabled, и он показывает, что мой NSArray с именем searchDataSource является зомби.

Когда вы вводите поисковый запрос, "shouldReloadTableForSearchTerm" выполняет функцию handleSearchForTerm. Функция handleSearchForTerm "получает доступ к моему классу ProductInfo, который запрашивает базу данных SQLite и возвращает результаты запроса. Затем эти результаты помещаются в мой массив searchDataSource. Все, кажется, работает там нормально. Однако, как только я добираюсь до функции" cellForRowAtIndexPath ", и я пытаюсь чтобы загрузить ячейки из searchDataSource, то есть когда я столкнулся с проблемой освобождения массива.

Вот мой код для контроллера поиска:

//
//  SearchViewController.h
//  Priority Wire
//
//  Created by Keith Yohn on 2/2/11.
//  Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import <UIKit/UIKit.h>


@interface FourthViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate> {
    UITableView *mainTableView;

    NSArray *searchDataSource;
    NSMutableArray *contentsList;
    NSMutableArray *searchResults;
    NSString *savedSearchTerm;
    NSString *webURL;
}

@property (nonatomic, retain) IBOutlet UITableView *mainTableView;
@property (nonatomic, retain) IBOutlet NSArray *searchDataSource;
@property (nonatomic, retain) NSMutableArray *contentsList;
@property (nonatomic, retain) NSMutableArray *searchResults;
@property (nonatomic, copy) NSString *savedSearchTerm;
@property (nonatomic, retain) NSString *webURL;

- (void)handleSearchForTerm:(NSString *)searchTerm;

@end

SearchViewController.m

//
//  SearchViewController.m
//  Priority Wire
//
//  Created by Keith Yohn on 2/2/11.
//  Copyright 2011 Priority Wire & Cable. All rights reserved.
//

#import "FourthViewController.h"
#import "ProductsDatabase.h"
#import "ProductInfo.h"
#import "WebViewController.h"

@implementation FourthViewController

@synthesize mainTableView;
@synthesize searchDataSource;
@synthesize contentsList;
@synthesize searchResults;
@synthesize savedSearchTerm;
@synthesize webURL;


- (void)viewDidLoad {
    [super viewDidLoad];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.searchDataSource count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }


    // Set up the cell...
    ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row]; //This is where I get the 'message sent to deallocated instance' message.
    [cell.textLabel setText:info.sName];
    [cell.detailTextLabel setText:info.sType];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row];

    webURL = [NSString stringWithFormat:@"http://www.prioritywire.com/specs/%@", info.sFile];

    WebViewController *wvController = [[WebViewController alloc] initWithNibName:@"WebViewController" bundle:[NSBundle mainBundle]];
    wvController.URL = webURL;
    wvController.navTitle = @"Spec Sheet";
    [self.navigationController pushViewController:wvController animated:YES];
    [wvController release];
}


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

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

- (void)viewDidUnload {
    [super viewDidUnload];

    // Save the state of the search UI so that it can be restored if the view is re-created.
    [self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];

    [self setSearchResults:nil];
}


- (void)dealloc {
    [searchDataSource release], searchDataSource = nil;
    [mainTableView release];
    [contentsList release];
    [searchResults release];
    [savedSearchTerm release];
    [super dealloc];
}

- (void)handleSearchForTerm:(NSString *)searchTerm
{   
    [self setSavedSearchTerm:searchTerm];

    if ([self searchResults] == nil)
    {
        NSMutableArray *array = [[NSMutableArray alloc] init];
        [self setSearchResults:array];
        [array release], array = nil;
    } else {
        NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
        self.searchDataSource = productInfo;
        [self.mainTableView reloadData];
        [productInfo release];
    }

    [[self searchResults] removeAllObjects];

    if ([[self savedSearchTerm] length] != 0)
    {
        for (NSString *currentString in [self contentsList])
        {
            if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
            {
                [[self searchResults] addObject:currentString];
            }
        }
    }
}

#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{   
    [self handleSearchForTerm:searchString];

    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
    [self setSavedSearchTerm:nil];
    self.searchDataSource = nil;
    [self.mainTableView reloadData];
}

@end

Я совершенно новичок в объективе-C и не могу понять, что я сделал неправильно. Я провел дни, пытаясь понять это, и мне не повезло. Буду признателен за любую помощь.

Keith

Ответы [ 2 ]

1 голос
/ 01 марта 2011

Этот бит кода, кажется, является единственным местом, где устанавливается searchDataSource:

    NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
    self.searchDataSource = productInfo;
    [self.mainTableView reloadData];
    [productInfo release];

Если ProductsDatabase следует правилам , вы не являетесь владельцем возвращенного массива (т.е.он уже автоматически выпущен), поэтому выпуск в четвертой строке неверен.

0 голосов
/ 01 марта 2011

Разве вы не хотите использовать searchResults массив вместо вашего searchDataSource, потому что в handleSearchForTerm: вы добавляете в него результаты. Почему у вас даже есть searchResult ивар? Он используется только в handleSearchForTerm:, может, там какая-то путаница?

...