Attaching an object to a UIActionSheet

百般思念 提交于 2019-12-01 11:29:15

The Objective-C 2.0 runtime supports associated objects - using this API, you can, euh, associate object with each other using a key-value method. Example:

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

Edit: it seems that you don't really need to shoot a bird usign a cannon and use runtime functions, since the same class/object that manages the alert sheet cares about the delegation also, so you could just assign it temporarily to an instance variable. However, this approach may be easier to extend later when your object model gets more complicated.

You could use my ActionSheetDelegate class to create a Block that will act in the stead of the actionSheet:clickedButtonAtIndex: method. Since the Block will be created in the same context as the creation of the action sheet, it can capture the object that you wish to delete:

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

You can also "associate" an object with another arbitrary object, using the Associated Objects runtime facility. In essence, this allows you to add an ivar to any instance at any time.

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

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

This just requires you to have a key variable somewhere. The docs suggest a file-level static char, whose address is used, as I've done here. Any value which will not change between setting and getting will work, however.

There are many ways to do this.

The simplest by far is just to give your parent view controller an instance variable that holds the object to be deleted. Since a UIActionSheet blocks other user interactions, it shouldn't be possible for the user to request deletion of a second object while the first object's deletion is pending.

The best way is to not present an action sheet at all, but just do the deletion and give the user an “undo” button.

You can use an associated object (see H2CO3's answer).

You can use a wrapper that lets you set up a block as the alert view's button handler (see Josh Caswell's answer or my own BlockActionSheet).

You can create a subclass of UIActionSheet and give it a property that holds the object pending deletion.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!