2

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

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

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

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

4

3 回答 3

5

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);

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

于 2012-10-06T19:32:57.480 回答
2

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

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

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

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

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

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

于 2012-10-06T19:36:02.143 回答
2

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

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

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

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

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

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

于 2012-10-06T19:33:09.650 回答