Ios 在UIActionSheet中存储上下文信息

Ios 在UIActionSheet中存储上下文信息,ios,objective-c,cocoa-touch,Ios,Objective C,Cocoa Touch,创建UIActionSheet以提示用户从列表中删除项目时,我当前必须将已删除的项目(或至少其在列表中的索引)作为实例变量保存在我的视图控制器中: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([indexPath row] == 4) { // Delete button pressed _deleting

创建
UIActionSheet
以提示用户从列表中删除项目时,我当前必须将已删除的项目(或至少其在列表中的索引)作为实例变量保存在我的视图控制器中:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([indexPath row] == 4) {
        // Delete button pressed
        _deletingItemIndex = [indexPath section];
        UIActionSheet actionSheet = ...
    }
}
然后当
UIActionSheet
关闭时,如果用户决定删除该项,我必须引用该
\u deletingItemIndex
变量,然后将其设置为
-1
或其他一些
nil

我想做的是在实际的
UIActionSheet
中维护删除项或其索引,而不需要子类
UIActionSheet


我觉得奇怪的是,
UIActionSheet
的委托方法为委托提供了工作表,但不能在工作表本身中存储任何上下文信息(甚至不能存储字典)。

您应该使用objc_setAssociatedObject()
请看一些代码。

现在有很多类别可用于向UIActionSheet和UIAlertView添加基于块的Dislose处理程序。我个人使用

这将让您执行以下操作

[UIActionSheet actionSheetWithTitle:@"Hooray" message:@"Blocks Are Awesome!" buttons:@[...] showInView:self onDismiss:^(int buttonIndex) {
    //Now you have access to all your local variables here!
} onCancel:^{
    //And here!
}];

UIActionSheet
是一个系统对象,它应该只关注向用户提供选项和获取按钮索引

使用视图控制器的实例变量也没有意义,因为这实际上不是视图控制器的状态,而是在用户开始删除时开始存在的当前操作

因此,正确的模式是创建一个新对象,将信息保存在其中,并用作委托

    MyDeletionAction *action = [MyDeletionAction actionWithIndex:[indexPath section]];
    UIActionSheet actionSheet = ...
    actionSheet.delegate = action;
    ...
在其他地方,将
MyDeletionAction
定义为实现委托协议的类

这种方法的另一个好处是,您可以将代码从视图控制器中提取到单独的类中,这是一件好事。此外,您的
MyDeletionAction
MyInsertionAction
等可能会共享一些公共代码

也许,甚至行动表的存在也应该是您行动的一个实施细节。例如,如果您提供了一个不经确认即可删除的选项,该怎么办

还要注意的是,在这种方法中,有人应该保留一个动作对象,例如,通过对象保留自己直到动作完全完成,或者为此目的使用VC实例变量:

   self.lastAction = [MyDeletionAction actionWithIndex:[indexPath section]];
   [self.lastAction start];
这还允许您记住最后一个操作的状态,以便进行可能的后处理


start
出现在这里是因为我的操作通常具有这种继承:
MyDeletionAction有趣-我通常不会看到为任务创建的一次性委托,根据我的经验,这种逻辑通常留给视图控制器。我在这里看到的一个潜在问题是,对象通常不会保留其
委托
属性,因此无论怎样,
操作
都需要在视图控制器中作为ivar进行维护,以避免被解除分配。是的,我已经扩展了答案来解释我的首选方法。我最终选择了这条路线。为它写了我自己的分类,但想法是一样的,而且效果很好。