简体   繁体   English

iOS-didSelectRowAtIndexPath导致应用崩溃

[英]iOS - didSelectRowAtIndexPath causes crash in app

I have a very strange problem that I don't understand. 我有一个我不明白的非常奇怪的问题。 I have a UITableView which causes a crash when I click on a row. 我有一个UITableView ,当我单击一行时会导致崩溃。

self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.delegate = self; <-- If I remove this, no crash caused
self.tableView.dataSource = self;

The funny thing is that I have no code at all inside didSelectRowAtIndexPath , and is still crashes? 有趣的是,在didSelectRowAtIndexPath内部没有任何代码,仍然崩溃? The log doesn't say much, I get (lldb) but when looking a bit further, I got this from debugger. 日志说的不多,我得到(lldb)但进一步看时,我是从调试器得到的。

[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] is the cause? [UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] I dont understand how to solve this problem. 我不明白如何解决这个问题。

Thread 1, Queue : com.apple.main-thread
#0  0x02b1909f in objc_msgSend ()
#1  0x01afb285 in -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] ()
#2  0x01afb4ed in -[UITableView _userSelectRowAtPendingSelectionIndexPath:] ()
#3  0x025055b3 in __NSFireDelayedPerform ()
#4  0x034f9376 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#5  0x034f8e06 in __CFRunLoopDoTimer ()
#6  0x034e0a82 in __CFRunLoopRun ()
#7  0x034dff44 in CFRunLoopRunSpecific ()
#8  0x034dfe1b in CFRunLoopRunInMode ()
#9  0x03b387e3 in GSEventRunModal ()
#10 0x03b38668 in GSEventRun ()
#11 0x01a4bffc in UIApplicationMain ()
#12 0x000125bd in main at /Users/damianmendez/dev/trigd/jagodu-ios/Jagodu/Jagodu/main.m:16
#13 0x03210725 in start ()

Anyone has any suggestions? 有人有建议吗? Thanks. 谢谢。

EDIT: After enabled zombies like @Phillip Millis told me too, I got this: 编辑:像@Phillip Millis这样的启用僵尸也告诉我,我得到了:

*** -[RefineSearchViewController tableView:didSelectRowAtIndexPath:]: message sent to deallocated instance 0x9d24030

UPDATE: 更新:

Code for adding RefineSearchViewController (which has a UITableView) 用于添加RefineSearchViewController (which has a UITableView)

RefineSearchViewController *refineSearchController = [[RefineSearchViewController alloc] initWithTransparentViews];
refineSearchController.parentDelegate = self.parentDelegate;

CGRect searchFrame = refineSearchController.view.frame;
searchFrame.origin.y = titleLabel.frame.origin.y + titleLabel.frame.size.height + 5;
refineSearchController.view.frame = searchFrame;

[self.refineSearchContainer addSubview:refineSearchController.view];    
[self.view addSubview:self.refineSearchContainer];

Code for initing RefineSearchViewController 初始化RefineSearchViewController代码

-(RefineSearchViewController*)init {
    self = [super init];

    if (self) {
        JoDModel *model = [JoDModel defaultModel];

        self.title = @"Search profile";
        _propertyNames = model.searchProfilePropertyNames;
        _properties = model.searchProfileProperties;
        _doneInvocation = nil;
        _isRefineSearch = NO;
        _transparentViews = NO;
    }

    return self;
}

-(RefineSearchViewController*)initWithTransparentViews {
    self = [self init];

    if (self) {
        _transparentViews = YES;
    }

    return self;
}

-(void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.titleShadow.hidden = !_addShadow;

    JoDModel *model = [JoDModel defaultModel];

    UIBarButtonItem *doneButton;

    if (_isRefineSearch) {
        doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Search" style:UIBarButtonItemStylePlain target:self action:@selector(done)];
        _keyboardBg = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, model.keyboardHeight)];
        _keyboardBg.backgroundColor = [UIColor blackColor];
        [self.view addSubview:_keyboardBg];
    } else {
        doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Search" style:UIBarButtonItemStylePlain target:self action:@selector(performSearch)];
    }

    self.navigationItem.rightBarButtonItem = doneButton;

    // When entering this view controller, the user will probably make a new search soon, therefore it's important to update the geo location
    if (model.shareMyLocation) {
        JoDAppDelegate *appDelegate = (JoDAppDelegate*)[UIApplication sharedApplication].delegate;
        [appDelegate updateLocation];
    }
}

-(void)dealloc {
    self.tableView = nil;
    _propertyNames = nil;
    _properties = nil;
    _doneInvocation = nil;
    _titleShadow = nil;
    _keyboardBg = nil;
}

You are creating the RefineSearchViewController as a local variable. 您正在将RefineSearchViewController创建为局部变量。 Assuming your project uses ARC, it will then be deallocated when that reference goes out of scope (end of the method that created it). 假设您的项目使用ARC,则当该引用超出范围(创建它的方法的结尾)时,它将被重新分配。

Make a strong property in the view controller that creates it and assign to that instead. 在创建它的视图控制器中创建一个强大的属性,然后分配给它。

Following last code pasted, it's normal your app crashes. 粘贴最后的代码后,您的应用正常崩溃。 Actually you should keep a reference to the new VC (RefineSearchViewController). 实际上,您应该保留对新VC的引用(RefineSearchViewController)。 To display its content, you do 要显示其内容,您可以

[self.refineSearchContainer addSubview:refineSearchController.view];    

[self.view addSubview:self.refineSearchContainer];

But the VC is lost. 但是VC丢失了。 You can use the container View controller mechanism with this method 您可以通过此方法使用容器View控制器机制

- (void)addChildViewController:(UIViewController *)childController

Or more easily use a NavigationController with a pushViewController: depending on what you want to do. 或更轻松地将NavigationController与pushViewController:根据您要执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM