按下了视图的“删除”按钮。该视图属于视图控制器,用于处理按钮按下。但是,该视图控制器是容器视图控制器的子代,因此它向其委托发送一条消息,指出要求删除,并包含应删除的对象。
委托(父视图控制器)接收通知并显示UIActionSheet
以确认删除。它还使自己成为该行动表的代表。
用户确认删除,父视图控制器已准备好删除该对象。除了必须在actionSheet:didDismissWithButtonIndex:
中执行此操作。到那时,它不再知道从子视图控制器传递了哪个对象。
有没有办法将对象附加到警报表,以便在触发解雇操作时,可以检索该对象?
答案 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的子类,并为其提供一个属性,以保留对象等待删除。