0

我在查找我的问题在我的搜索控制器中时遇到了一个真正的问题。这是一个带有搜索栏和搜索显示控制器的表格视图。它曾经工作正常,但突然停止工作。我打开了 NSZombieEnabled,它显示我的名为 searchDataSource 的 NSArray 是僵尸。

当您键入搜索词时,“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

搜索视图控制器.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

我对 Objective-C 很陌生,无法理解我做错了什么。我花了几天时间试图解决这个问题,但没有运气。我将不胜感激任何人都可以提供的帮助。

基思

4

2 回答 2

1

这段代码似乎是唯一设置 searchDataSource 的地方:

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

如果ProductsDatabase遵循规则,则您不拥有返回的数组(即它已经自动释放),因此第四行的释放不正确。

于 2011-03-01T01:27:41.237 回答
0

您不是要使用您的searchResults-array 而不是您的searchDataSource,因为handleSearchForTerm:您正在将结果添加到其中。为什么你还有searchResultivar?它只用于handleSearchForTerm:,也许有一些混淆?

于 2011-02-28T22:42:15.320 回答