2

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

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

popoverSelected是 的委托方法UIPopoverController,其中包含一个简单的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];
    }
}

弹出框由通过上的 TouchUpInside 操作实例化self.button

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

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

我看不到我意外释放按钮的任何地方(此时该对象肯定仍然存在)。该项目正在使用ARC。

使用 NSZombies,我偶尔会接触到[__NSArrayI valueRestriction] unrecognised selector sent to instance,这更没有意义。

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

4

1 回答 1

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 的实现。如果您也可以发布该视图控制器,我会为您查看。

于 2013-11-07T16:52:03.787 回答