16

我想知道如何将 userInfo 对象或任何 NSDictionary 添加到 UIAlertView?

谢谢你。

4

5 回答 5

31

您可以尝试子类化 UIAlertView 以添加该字段,或者将引用存储在您的委托类中。但是将任何对象附加到任何其他对象的最通用方法是使用objc_setAssociatedObject.

为此,您必须#import <objc/runtime.h>,并且您需要一个void *用作键的任意键(通常的技巧是static char fooKey;在您的 .m 文件中声明 a 并使用其地址)。然后你可以像这样附加对象:

objc_setAssociatedObject(alertView, &fooKey, myDictionary, OBJC_ASSOCIATION_RETAIN);

在这种情况下,myDictionary 将在 alertView 的整个生命周期内保留,并在 alertView 被释放时释放。

要稍后检索您的关联对象,请使用逻辑命名的objc_getAssociatedObject.

NSDictionary *myDictionary = objc_getAssociatedObject(alertView, &fooKey);

nil如果没有关联集则返回。要打破关联,只需使用objc_setAssociatedObject为同一个对象和键关联一个新值;nil可用于在不关联新对象的情况下中断关联。

此处列出了除 OBJC_ASSOCIATION_RETAIN 之外的关联类型的其他值。

于 2011-03-12T01:13:16.110 回答
15

我写了一个(经过充分测试的)类别NSObject,使每个对象都能够轻松存储数据。

只需将代码放在头文件和实现文件中,然后将其导入您的任何项目中。或者把它放在一个静态库中。仅限 Mac OS X 10.6+ 和 iOS(版本?)。

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface NSObject (CCFoundation)

- (id)associativeObjectForKey: (NSString *)key;
- (void)setAssociativeObject: (id)object forKey: (NSString *)key;

@end

#pragma mark -

@implementation NSObject (CCFoundation)

static char associativeObjectsKey;

- (id)associativeObjectForKey: (NSString *)key {
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
    return [dict objectForKey: key];
}

- (void)setAssociativeObject: (id)object forKey: (NSString *)key {
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
    if (!dict) {
        dict = [[NSMutableDictionary alloc] init];
        objc_setAssociatedObject(self, &associativeObjectsKey, dict, OBJC_ASSOCIATION_RETAIN);
    } [dict setObject: object forKey: key];
}

@end

简而言之,只要NSMutableDictionary您需要,每个对象都会成为易于使用的字典(感谢 )。字典在对象被释放时被释放,字典的对象在字典被释放时被释放。令人惊讶的是,Apple 如何让这一切变得简单。

警告 1:上面的代码是ARC 启用的。它经过了良好的测试,并用于多种已发货的产品中。我还没有看到任何内存泄漏或性能问题。

警告 2:根据需要重命名方法,但如果选择保留名称,请确保添加前缀。这是根对象 people 上的一个类别。某处的某个类正在使用此方法名称,您不想干涉!我在每个项目中都包含的静态库使用方法名称associativeCCObjectForKey:setAssociativeCCObject:forKey:.

我希望这可以帮助任何想要userInfo在每个对象上都具有类似简单功能的人。别客气!:-)

于 2012-04-25T15:45:21.500 回答
11

如果您使用的是 > iOS 4.0(用于块)并且您只想要一个或两个按钮,您可以使用我制作的这个类别:

https://github.com/rsaunders100/UIAlertView-Blocks

它绕过了添加用户信息的需要,因为您将点击处理功能直接放入警报中。例如

 #import UIAlertView+Blocks.h

 ...

 ...

 NSString* myUserInfo = @"example";

 [UIAlertView displayAlertWithTitle:@"Example Alert View With Blocks"
                            message:nil
                    leftButtonTitle:@"Ok"
                  leftButtonAction:^{
                                      NSLog(@"%@", myUserInfo);
                                    } 
                  rightButtonTitle:nil
                 rightButtonAction:nil];
于 2012-01-24T09:37:37.263 回答
4

如果我给它一个文字 c 字符串(例如“key”)而不是创建一个静态字符,它对我有用

相反,考虑到 Anomie 所说的,您可以这样做:

objc_setAssociatedObject ( alert , (const void*)0x314 , notification , OBJC_ASSOCIATION_RETAIN ) ;

这适用于任何允许您使用任意 void*(观察、此函数等)并且不需要额外的静态变量技巧的东西。此外,(const void*)0x314 始终为 0x314,无论编译器做什么。

另外,Anomie,你刚刚在我正在开发的应用程序中为我节省了很多工作。谢谢!

于 2011-08-08T23:33:56.817 回答
1

我想出了一个更简单的解决方案,可能适合某些情况。因为您在调用委托时获得了 NSAlertView 上下文,所以我使用对象的实际地址来创建一个标记 (NSString*),然后我使用该标记将自定义值存储在全局或对象特定的 NSDictionary 中。这是一个例子:

+(NSString*)GetTag:(id)ObjectIn
{
    return [NSString stringWithFormat:@"Tag-%i",(int)ObjectIn];
}

在代表中:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString* MyID = [CommandManager GetTag:alertView];
    [CurrentActiveAlerts removeObjectForKey:MyID];
}

来电:

    UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:title_text
                                                          message:@""
                                                     delegate:self
                                            cancelButtonTitle:nil
                                        otherButtonTitles:button_text ,nil];

    CurrentActiveAlerts[[CommandManager GetTag:myAlert]] = CommandToRun;  
    [myAlert show];
    [myAlert release];

这些键最终看起来像“Tag-226811776”。希望这可以帮助。

于 2014-01-20T16:00:51.317 回答