使用 UISearchBar 方法导致 EXC_BAD_ACCESS 崩溃
我有一个 UISearchBar 设置,当使用它时,它有一个覆盖灰色视图的覆盖层,类似于苹果的做法。
当我单击这个变暗的视图时,它会退出搜索模式,这很好,但是当我再次搜索,然后再次单击灰色退出时,它会因 EXC BAD ACCESS 错误而崩溃。
以下是一些相关代码:
崩溃始终发生在 [rvController didSearching_Clicked:nil];< /code>
OverlayViewController.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
带搜索栏的实际 VC 代码
- (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];
}
I have a UISearchBar setup and when its being used, it has an overlay grey view that covers the rest of the table similar to how apple does it.
When I click this darkened view, it exits search mode, which is good, but when I search again, then again click the grey to exit, it crashes with EXC BAD ACCESS error.
Here is some related code:
The crash is always at [rvController doneSearching_Clicked:nil];
OverlayViewController.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
Code for the actual VC with the search bar
- (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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
Point 1
处,它会调用-(void)doneSearching_Clicked
,然后执行Point 2
。在Point 2
处,我认为OverlayView
对象的retainCount将为0,这意味着它将被释放。因此,OverlayView
拥有的所有指针都可能无效,因为它在-(void)dealloc
中释放了这些对象。根据你的代码,我只能知道这些。编辑:
上述过程可以翻译为以下格式。
-doneSearching_Click
将导致[self release]
行为。At the
Point 1
, it will call-(void)doneSearching_Clicked
, then it will executePoint 2
. AtPoint 2
, I think theOverlayView
object's retainCount will be 0, that means it will deallocated. So, all pointers theOverlayView
has may be invalid, because it releases those objects in-(void)dealloc
. According to your codes, that is all I can know.Edit:
The above procedures may be translated as following format. The
-doneSearching_Click
will result in[self release]
behavior.您的代码并不完全是不言自明的,但我猜您过度释放了
ovController
。您位于ovController
的touchesBegan:
方法中,然后让它执行不同对象rvContller
中的方法,该对象 释放调用对象。当尝试从方法调用返回到已释放的控制器时,您会收到错误访问错误。Your code is not completely self explanatory, but I would guess that you are over-releasing
ovController
. You are in theovController
'stouchesBegan:
method, then you have it execute a method in a different object,rvContrller
, which releases the calling object. When trying to return from the method call to the released controller you get the bad-access error.