0

問題が検索コントローラーのどこにあるかを見つけるのに本当に問題があります。これは、検索バーと検索表示コントローラーを備えたテーブル ビューです。以前は問題なく動作していましたが、突然動作しなくなりました。NSZombieEnabled をオンにすると、searchDataSource と呼ばれる NSArray がゾンビであることがわかります。

検索語を入力すると、「shouldReloadTableForSearchTerm」が handleSearchForTerm 関数を実行します。handleSearchForTerm" 関数は、SQLite データベースにクエリを実行してクエリ結果を返す ProductInfo クラスにアクセスします。これらの結果は 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

私はobjective-Cにまったく慣れていないので、何が間違っていたのか理解できません。私はこれを理解しようと何日も費やしましたが、運がありませんでした。誰でも提供できる助けをいただければ幸いです。

キース

4

2 に答える 2

1

このコードは、searchDataSource が設定される唯一の場所のようです。

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

ルールProductsDatabaseに従う場合、返された配列を所有していない (つまり、既に自動解放されている) ため、4 行目の解放は正しくありません。

于 2011-03-01T01:27:41.237 に答える
0

結果を追加しているため、searchResults-array の代わりに -arrayを使用するつもりはありませんか。なぜあなたはivarさえ持っているのですか?これは handleSearchForTerm: でのみ使用されます。searchDataSourcehandleSearchForTerm:searchResult

于 2011-02-28T22:42:15.320 に答える