setTitle:forState上的UIButton EXC_BAD_ACCESS

时间:2013-10-29 18:07:39

标签: ios objective-c

我有一个从IB实例化的视图控制器。它包含一个UIButton,其动作创建一个UIPopoverController,其委托通过以下方式更新UIButton的标题:

- (void) popoverSelected:(NSString*)string {
    [self.sortButton setTitle:string forState:UIControlStateNormal];
    [self.sortPickerPopover dismissPopoverAnimated:YES];
}

popoverSelectedUIPopoverController的委托方法,其中包含一个简单的UITableView

#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *selectedSort = [_sortTypes objectAtIndex:indexPath.row];

    if (_delegate != nil) {
        [_delegate popoverSelected:selectedSort];
    }
}

弹出窗口由self.button上的TouchUpInside操作实例化:

- (IBAction)sortButtonPressed:(id)sender {
    if (_sortPicker == nil) {
        // Create the picker view controller
        _sortPicker = [[SortPickerViewController alloc] initWithStyle:UITableViewStylePlain];

        // Set this as the delegate
        _sortPicker.delegate = self;
    }

    if (_sortPickerPopover == nil) {
        // The colour picker popover is not showing. Show it
        _sortPickerPopover = [[UIPopoverController alloc] initWithContentViewController:_sortPicker];
        [_sortPickerPopover presentPopoverFromRect:_sortButton.frame
                                            inView:self.view
                          permittedArrowDirections:UIPopoverArrowDirectionAny
                                          animated:YES];
    } else {
        // if it's showing, we want to hide it
        [_sortPickerPopover dismissPopoverAnimated:YES];
        _sortPickerPopover = nil;
    }
}

第一次更新按钮标题时没有问题,但第二次执行setTitle:EXC_BAD_ACCESS时,我得到popoverSelected

我无法看到任何意外发布按钮的东西(此时对象肯定仍然存在)。该项目正在使用ARC。

对于NSZombies,我偶尔会遇到[__NSArrayI valueRestriction] unrecognised selector sent to instance,这更不合理。

我可以采取哪些明显的方法来进一步调试吗?

1 个答案:

答案 0 :(得分:0)

您应该检查_sortPickerPopover == nil,而不是检查[_sortPickerPopover isPopoverVisible]是否要显示它。另外,我会将构造代码放入自动加载器中。

- (UIPopoverController *)sortPickerPopover
{
    if (!_sortPickerPopover) {
        _sortPickerPopover = [[UIPopoverController alloc] initWithContentViewController:self.sortPicker];
    }
    return _sortPickerPopover;
}

- (SortPickerViewController *)sortPicker
{
    if (!_sortPicker) {
        _sortPicker = [[SortPickerViewController alloc] initWithStyle:UITableViewStylePlain];

        // Set this as the delegate
        _sortPicker.delegate = self;
    }
    return _sortPicker;
}

- (IBAction)sortButtonPressed:(UIButton *)sender 
{
    if ([self.sortPickerPopover isPopoverVisible]) {
        [self.sortPickerPopover dismissPopoverAnimated:YES];
    } else {
            [self.sortPickerPopover presentPopoverFromRect:sender.frame
                                                    inView:sender
                                  permittedArrowDirections:UIPopoverArrowDirectionAny
                                                  animated:YES];
    }
}

/***
 * NOTE: Delegate methods should always pass the calling object as the first 
 * object. Additionally, the name is not very descriptive of what is actually
 * being performed and does not use should/will/did naming conventions.
 * You should consider changing this method to something like:
 *  - (void)sortPickerViewController:(SortPickerViewController *)sortPicker   
 *               didSelectSortMethod:(NSString *)sortMethod
 **/
- (void)popoverSelected:(NSString *)string 
{
    [self.sortButton setTitle:string forState:UIControlStateNormal];
    [self.sortPickerPopover dismissPopoverAnimated:YES];
}

一旦做出这些更改,唯一可能的其他问题源是SortPickerViewController的实现。如果你也可以发布那个视图控制器,我会为你看看。