5

I have a UITextField that I am adding to a UITableViewCell to use as a search field for a long list of accounts. I have added it as follows:

- (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];
    }

    if ((indexPath.section < accountsection) && (hasSearch) && (indexPath.row == 0)) 
    {
        // Search
        if (!searchField) 
        {
            searchField = [[UITextField alloc] initWithFrame:CGRectMake(20, 10, cell.frame.size.width - 40, 25)];
            [searchField setEnabled:YES];
            searchField.placeholder = NSLocalizedString(@"Search", @"search");
            searchField.keyboardType = UIKeyboardTypeDefault;
            searchField.returnKeyType = UIReturnKeySearch;
            searchField.autocorrectionType = UITextAutocorrectionTypeNo;
            searchField.clearButtonMode = UITextFieldViewModeAlways;
            searchField.delegate = self;
            [cell addSubview:searchField];
            [searchField release];
        }

        // Clean up an account label if needed
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.textLabel.text = @"";
        cell.detailTextLabel.text = @"";

        // Show the search field if it was hidden by a text label
        searchField.hidden = NO;
        [cell bringSubviewToFront:searchField];
    } 
}

To detect edits to the text field, I have set up the UITextFieldDelegate in the header and trap the following delegate calls:

@interface AccountViewController : UITableViewController <UITextFieldDelegate> {
    BOOL hasSearch;    
    UITextField *searchField;
...
}

In the implementation, I then handle these delegate methods:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"Done editing");
    [self filterAccountsBy:textField.text];
    [textField resignFirstResponder];
    return NO;
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSLog(@"Searching for %@", string);
    [self filterAccountsBy:string];    
    return YES;
}

However in the second one, unless I return YES, the text never changes; in the first one, returning YES seems to not affect me. But when I return YES in either, I get a nasty EXC_BAD_ACCESS.

I must be missing something in my manual adding of this UITextField to my cell but I can't figure out what it is... can anyone assist?

Many thanks.


EDIT: As suggested below, I commented out the filterAccounts call and my app now no longer crashes. Here is the full code for this method:

- (void)filterAccountsBy:(NSString *)filterstring 
{
    [accounts removeAllObjects];
    if (([filterstring length] == 0) && (!isChooser) && (![vpmsConn isDomainLogon])) {
        [accounts addObject:[[vpmsConn accounts] objectAtIndex:0]];
    } 

    if ([filterstring length] == 0) {
        [accounts addObjectsFromArray:[cache accounts]];
    } else {
        for (AccountItem *ac in [cache accounts]) 
        {           
            BOOL found = NO;

            // Name search
            if ([[ac.clientName uppercaseString] rangeOfString:[filterstring uppercaseString]].location != NSNotFound) {
                found = YES;
            }

            //more similar searches

            if (found) {
                [accounts addObject:ac];
            }
        }   
    }

    [self.tableView reloadData];
}

I am a bit confused, though. When I filter this list using the textFieldShouldReturn and then return NO, it filters properly and does not crash. Something about returning YES from either one of these methods causes the crash after I have filtered. If I have not filtered at all, returning YES is no problem.

Let me know if there is any other code that I should post.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
hocker
  • 688
  • 6
  • 18
  • What is `filterAccountsBy:`? Does it crash if you comment it out? – albertamg Jul 11 '11 at 18:40
  • That method simply filters the accounts by the text provided; it basically does the following to the NSMutableArray: remove all objects, then add new ones back, then call reloadData on the tableview which uses that array as its data source. – hocker Jul 12 '11 at 14:14
  • However as you surmise, it does actually crash when the method is enabled and doesn't when it is commented out. Which makes me wonder now what this method is doing wrong. I will post the complete method code above. – hocker Jul 12 '11 at 15:53
  • Can you post the crash log or the `backtrace`? – Deepak Danduprolu Jul 12 '11 at 16:11
  • Sorry if this sounds like a silly question but how do I get a backtrace/crash log? – hocker Jul 12 '11 at 18:44
  • You found the issue already (grats), but for future, when you want to post a backtrace, you can either grab it from Xcode (select the trace and cmd-c copy it), or you can type "bt" in gdb in console and select & copy the output. – Kalle Dec 16 '11 at 16:31

4 Answers4

0

I think your UITextField searchfield is begin deallocated. If you use self.searchField to set your searchfield (assuming it's a retained property), that will solve it.

I'm not sure what the rest of your .h looks like. You could do:

@property (nonatomic, retain) UITextField *searchField;

Then in the .m:

@synthesize searchField;

That's what I mean by making search field a retained property. This way your class will keep the search field around.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
Matthew Horst
  • 1,991
  • 15
  • 18
  • I tried this and it has no effect. From the previous commenter's edits, something is happening with my filter logic. I am going to edit the original question to add this code... – hocker Jul 12 '11 at 15:55
  • If you turn on zombies you should be able to find out what object is being referenced after being released. This should help you narrow down the problem (http://stackoverflow.com/questions/2190227/how-do-i-set-nszombieenabled-in-xcode-4) – Matthew Horst Jul 12 '11 at 17:25
  • Actually, I have enabled zombies exactly as that link describes - Xcode 4 just unhelpfully dumps me at the main() function. I will post the backtrace above... – hocker Jul 12 '11 at 17:52
0

I have resolved the issue but I cannot (due to NDA) post the answer here yet. Those interested, and in the paid iOS developer program, should go to the NDA developer forums and search for UITextField EXC_BAD_ACCESS and you will find the answer...

hocker
  • 688
  • 6
  • 18
0

in

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

where is

return cell;

?

UnRewa
  • 2,462
  • 2
  • 29
  • 31
0

In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathreturn cell;

Donot release serachfield in the event;

Release in dealloc

add @property (nonatomic, retain) UITextField *searchField;

Paresh Navadiya
  • 38,095
  • 11
  • 81
  • 132