0

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.

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? The log doesn't say much, I get (lldb) but when looking a bit further, I got this from debugger.

[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] is the cause? 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:

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

UPDATE:

Code for adding 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*)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;
}
Carnal
  • 21,744
  • 6
  • 60
  • 75
  • 1
    A couple of debugging suggestions: run with zombies on and see if you get better error information, log some message in a `didSelectRowAtIndexPath` method and see if it executes. (I'm surprised that the console log doesn't say what `objc_msgSend` is trying to target.) – Phillip Mills Dec 16 '13 at 13:44
  • Are you calling method "didSelectRowAtIndexPath" as custom? – sathiamoorthy Dec 16 '13 at 13:44
  • Can you go to the "Breakpoint navigator" and add exception breakpoint for all exceptions? Then you can print the exception trace here, and that will help us to investigate it. You can follow this: http://stackoverflow.com/a/14767076/1582255 – rordulu Dec 16 '13 at 13:46
  • I tried to do NSLog inside didSelect, but it was not executed. I'll look into the debugger now and see if I can find anything more clear. – Carnal Dec 16 '13 at 13:50
  • @Phillip Mills: How can I do that? I tried to NSLog inside didSelect method, but it is not executed. – Carnal Dec 16 '13 at 13:57
  • is there anything which is releasing in cellForRowAtIndexPath? – Retro Dec 16 '13 at 13:58
  • (Assuming you're asking about zombies...) If you edit your current build scheme, there's a tab in the "Run" section called "Diagnostics". One of its checkboxes says "Enable Zombie Objects". – Phillip Mills Dec 16 '13 at 14:03
  • post some code regarding delegate methods – Vijay-Apple-Dev.blogspot.com Dec 16 '13 at 14:04
  • This app was to begin with compatible with iOS4. Later we changed the target to iOS6 and converted to ARC. But i can't see anything relevant in the code for each row that is releasing, maybe the way we init the cell? I have 2 different inflates for these cells. – Carnal Dec 16 '13 at 14:04
  • @Phillip Millis: I enabled those zombies, and got another print now, can you have a look? I edited my question. – Carnal Dec 16 '13 at 14:22
  • 3
    The new message is pointing you at the object that is causing the problem. Whatever a `RefineSearchViewController` is, it's being deallocated before it has a chance to handle the table view selection. We probably need information about how that object is created and referenced to say much more than that. – Phillip Mills Dec 16 '13 at 14:27
  • @Phillip Mills: I have added the code now. RefineSearchViewController is inited programmaticaly in another ViewController (in order to make a transparent "popup"). – Carnal Dec 16 '13 at 14:38

2 Answers2

2

You are creating the RefineSearchViewController as a local variable. Assuming your project uses ARC, it will then be deallocated when that reference goes out of scope (end of the method that created it).

Make a strong property in the view controller that creates it and assign to that instead.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
1

Following last code pasted, it's normal your app crashes. Actually you should keep a reference to the new VC (RefineSearchViewController). To display its content, you do

[self.refineSearchContainer addSubview:refineSearchController.view];    

[self.view addSubview:self.refineSearchContainer];

But the VC is lost. You can use the container View controller mechanism with this method

- (void)addChildViewController:(UIViewController *)childController

Or more easily use a NavigationController with a pushViewController: depending on what you want to do.

Geraud.ch
  • 1,499
  • 10
  • 15
  • Thanks for the tip, making the property as strong was good enough! – Carnal Dec 16 '13 at 14:50
  • Using my first method has one more advantage: the child viewController automatically receives the VC life cycle methods: viewWillAppear, viewWillDisappear, ... – Geraud.ch Dec 16 '13 at 15:08