将对象附加到UIActionSheet

时间:2012-10-06 19:25:24

标签: objective-c cocoa-touch uiactionsheet

按下了视图的“删除”按钮。该视图属于视图控制器,用于处理按钮按下。但是,该视图控制器是容器视图控制器的子代,因此它向其委托发送一条消息,指出要求删除,并包含应删除的对象。

委托(父视图控制器)接收通知并显示UIActionSheet以确认删除。它还使自己成为该行动表的代表。

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

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

3 个答案:

答案 0 :(得分: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);

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

答案 1 :(得分:2)

您可以使用my ActionSheetDelegate class创建一个代替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
}];

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

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

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

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

答案 2 :(得分:2)

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

到目前为止,最简单的方法是为父视图控制器提供一个实例变量,用于保存要删除的对象。由于UIActionSheet阻止了其他用户交互,因此当第一个对象的删除未决时,用户不应该请求删除第二个对象。

最好的方法是根本不提供动作表,只是删除并给用户一个“撤销”按钮。

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

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

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