将对象附加到 UIActionSheet

Posted

技术标签:

【中文标题】将对象附加到 UIActionSheet【英文标题】:Attaching an object to a UIActionSheet 【发布时间】:2012-10-06 19:25:23 【问题描述】:

按下视图的“删除”按钮。该视图属于一个视图控制器,它处理按钮按下。但是,该视图控制器是容器视图控制器的子级,因此它会向其委托发送一条消息,说明已请求删除,并包含应删除的对象。

委托(父视图控制器)收到通知并提供@​​987654321@ 以确认删除。它还使自己成为该操作表的代表。

用户确认删除,父视图控制器准备删除对象。除非它必须在actionSheet:didDismissWithButtonIndex: 中执行此操作。到那时,它不再知道哪个对象是从子视图控制器传下来的。

有没有办法将对象附加到警报表,以便在触发解除操作时,可以检索该对象?

【问题讨论】:

【参考方案1】:

Objective-C 2.0 运行时支持关联对象 - 使用此 API,您可以使用键值方法将对象彼此关联。示例:

id someObject = // however you obtain it
objc_setAssociatedObject(theActionSheet, "AssociatedDelegateObject", someObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

// later try to get the object:
id someObject = objc_getAssociatedObject(theActionSheet, "AssociatedDelegateObject");
// process the associated object, then release it:
objc_removeAssociatedObjects(theAlertSheet);

编辑:似乎你真的不需要用大炮射击鸟并使用运行时函数,因为管理警报表的同一个类/对象也关心委托,所以你可以暂时分配它到一个实例变量。但是,当您的对象模型变得更复杂时,这种方法可能更容易扩展。

【讨论】:

我也可以暂时将对象转储到 iVar 中,我想 - 将它与警报表关联有什么好处? (我承认我的问题专门询问了“附加”)。 通过继承UIAlertSheet,添加retain 属性可以实现相同的功能。 @BenPackard 没有太多好处。我认为您需要这是因为您的问题表明对象层次结构/模型中的距离太大,以至于您无法直接访问操纵警报表的两个对象。 @Sulthan 除了 UIAlertView 不能被子类化。 @H2CO3 没有UIAlertSheetUIActionSheet 文档中没有任何内容说不要子类化它。也许你在想UIAlertView【参考方案2】:

您可以使用 my ActionSheetDelegate class 创建一个 Block 来代替 actionSheet:clickedButtonAtIndex: 方法。由于 Block 将在与创建操作表相同的上下文中创建,因此它可以捕获您希望删除的对象:

ActionSheetDelegate * delegate;
delegate = [ActionSheetDelegate delegateWithHandler:
    ^( UIActionSheet * sheet, NSInteger idx )
        if( idx == [sheet destructiveButtonIndex] )
            [self destroyObject:obj];
        
        // Cancel button "falls through" to no action
];

您还可以使用Associated Objects runtime facility 将一个对象与另一个任意对象“关联”。从本质上讲,这允许您随时将 ivar 添加到任何实例。

// Set:
objc_setAssociatedObject(sheet, &key, objectToDestroy, OBJC_ASSOCIATION_RETAIN);

// Retrieve:
id objectToDestroy = objc_getAssociatedObject(sheet, &key);

这只需要你在某处有一个key 变量。文档建议使用文件级static char,正如我在这里所做的那样。但是,任何在设置和获取之间不会改变的值都可以使用。

【讨论】:

【参考方案3】:

有很多方法可以做到这一点。

目前最简单的方法就是给你的父视图控制器一个实例变量来保存要删除的对象。由于UIActionSheet 会阻止其他用户交互,因此用户不可能在第一个对象的删除待处理时请求删除第二个对象。

最好的方法是根本不显示操作表,而只是删除并给用户一个“撤消”按钮。

您可以使用关联对象(请参阅 H2CO3 的答案)。

您可以使用包装器,将块设置为警报视图的按钮处理程序(请参阅 Josh Caswell 的回答或我自己的 BlockActionSheet)。

您可以创建 UIActionSheet 的子类,并为其提供一个属性来保存待删除的对象。

【讨论】:

以上是关于将对象附加到 UIActionSheet的主要内容,如果未能解决你的问题,请参考以下文章

无法快速将对象附加到对象数组

Python - 将 JSON 对象传递给函数时附加到 JSON 对象的附加“成员”

如何将对象附加到表中

将字典对象附加到 UITableViewCell

将委托附加到数组中的对象

WPF 将 VisualState 附加到对象属性