Получение сбоя EXC_BAD_ACCESS с помощью метода UISearchBar

У меня есть настройка UISearchBar, и когда она используется, она имеет наложенный серый вид, который покрывает остальную часть таблицы, подобно тому, как это делает Apple.

Когда я нажимаю на этот затемненный вид, он выходит из режима поиска, что хорошо, но когда я снова ищу, а затем снова нажимаю на серый, чтобы выйти, он вылетает с ошибкой EXC BAD ACCESS.

Вот некоторый связанный код:

введите здесь описание изображения

Сбой всегда в [rvController doneSearching_Clicked:nil];

Оверлейвиевконтроллер.h

@interface OverlayViewController : UIViewController

@property (nonatomic, retain) ChooserViewController *rvController;
@property (nonatomic, retain) CPTViewController *cptViewController;


@implementation OverlayViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [rvController doneSearching_Clicked:nil];
    [cptViewController doneSearching_Clicked:nil];
}

- (void) dealloc {
    [rvController release];
    [cptListViewController release];
    [super dealloc];
}

@end

Код для актуального ВК со строкой поиска

- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar
{
    searching = YES;
    [ovController.view removeFromSuperview];
    letUserSelectRow = YES;
    self.tableView.scrollEnabled = YES;
    if (self.mySearchBar.text !=nil)
    {
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"(name contains[cd] %@) OR (code contains[cd] %@)", self.mySearchBar.text, self.mySearchBar.text];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
    }
    else
    {
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
    }

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) 
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    } 

    self.searchArray = fetchedResultsController.fetchedObjects;

    [mySearchBar resignFirstResponder];

    [self.tableView reloadData];
}

- (void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    self.navigationItem.leftBarButtonItem = nil;

    if(searching)
        return;

    if(ovController == nil)
        ovController = [[OverlayViewController alloc] initWithNibName:@"OverlayView" bundle:[NSBundle mainBundle]];

    CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height;

    CGRect frame = CGRectMake(0, yaxis, width, height);
    ovController.view.frame = frame;    
    ovController.view.backgroundColor = [UIColor grayColor];
    ovController.view.alpha = 0.5;

    ovController.rvContrller = self;

    [self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];

    searching = YES;
    letUserSelectRow = NO;
    self.tableView.scrollEnabled = NO;

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] 
                                               initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
                                               target:self action:@selector(doneSearching_Clicked:)] autorelease];
}

- (void) searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = NO;
}

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText 
{
    [self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];

    searching = NO;
    letUserSelectRow = NO;
    self.tableView.scrollEnabled = NO;

    [self.tableView reloadData];
}
- (void) doneSearching_Clicked:(id)sender {

    mySearchBar.text = @"";
    [mySearchBar resignFirstResponder];

    letUserSelectRow = YES;
    searching = NO;
    self.navigationItem.rightBarButtonItem = nil;
    self.tableView.scrollEnabled = YES;

    [ovController.view removeFromSuperview];
    [ovController release];
    ovController = nil;

    [self.tableView reloadData];
    [self.tableView scrollToRowAtIndexPath:0 atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

person Jon    schedule 07.09.2011    source источник
comment
В какой строке вы получаете эту ошибку?   -  person akashivskyy    schedule 07.09.2011
comment
Сбой всегда в [rvController doneSearching_Clicked:nil];   -  person Jon    schedule 07.09.2011
comment
Опубликуйте, что в журнале сбоя консоли говорится о трассировке вызова функции.   -  person SayeedHussain    schedule 07.09.2011
comment
Спасибо, я добавил скриншот стека трассировки в вопрос.   -  person Jon    schedule 07.09.2011
comment
консоль должна выдавать вам какое-то сообщение или как вы узнали, что это EXC_BAD_ACCESS   -  person SayeedHussain    schedule 07.09.2011
comment
Спасибо, я добавил скриншот стека трассировки в вопрос В консоли просто есть это mem 0x1000 0x3fffffff cache mem 0x40000000 0xffffffff none mem 0x00000000 0x0fff none [Switching to process 11779 thread 0x0] [Switching to process 11779 thread 0x0] (gdb)   -  person Jon    schedule 07.09.2011


Ответы (2)


/// @OverlayView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [rvController doneSearching_Clicked:nil]; ///< Point 1
    [cptViewController doneSearching_Clicked:nil];
}

/// @VC Search bar
- (void) doneSearching_Clicked:(id)sender {

    mySearchBar.text = @"";
    [mySearchBar resignFirstResponder];

    letUserSelectRow = YES;
    searching = NO;
    self.navigationItem.rightBarButtonItem = nil;
    self.tableView.scrollEnabled = YES;

    /// Point 2 
    [ovController.view removeFromSuperview];
    [ovController release];
    ovController = nil;

    [self.tableView reloadData];
    [self.tableView scrollToRowAtIndexPath:0 atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

В Point 1 он вызовет -(void)doneSearching_Clicked, затем выполнит Point 2. Я думаю, что в Point 2 объект OverlayView будет иметь значение 0, это означает, что он будет освобожден. Таким образом, все указатели, которые есть у OverlayView, могут быть недействительными, потому что он освобождает эти объекты в -(void)dealloc. Согласно вашим кодам, это все, что я могу знать.

Редактировать:
Вышеуказанные процедуры могут быть переведены в следующем формате. -doneSearching_Click приведет к [self release] поведению.

/// @OverlayView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [rvController doneSearching_Clicked:nil]; ///< Point 1
    /// [self release];  /// the above method will do such thing.
    [cptViewController doneSearching_Clicked:nil];
}
person AechoLiu    schedule 08.09.2011

Ваш код не совсем понятен, но я предполагаю, что вы выпускаете слишком много ovController. Вы находитесь в методе touchesBegan: ovController, затем он выполняет метод в другом объекте, rvContrller, который освобождает вызывающий объект. При попытке вернуться из вызова метода к выпущенному контроллеру вы получаете ошибку плохого доступа.

person Mundi    schedule 07.09.2011
comment
Извините, это опечатка, везде rvController. - person Jon; 07.09.2011