如何将userInfo添加到UIAlertView?

时间:2011-03-12 00:31:28

标签: iphone objective-c nsdictionary uialertview userinfo

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

谢谢。

5 个答案:

答案 0 :(得分:31)

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

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

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之外的关联类型的其他值here

答案 1 :(得分: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:根据需要重命名方法,但如果您选择保留名称,请确保添加前缀。这是一个根对象的类别,人。某个类在某处使用此方法名称,您不想干涉!我在每个项目中包含的静态库使用方法名称associativeCCObjectForKey:setAssociativeCCObject:forKey:

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

答案 2 :(得分:11)

如果你在&gt; iOS 4.0(对于块)你只需要一个或两个按钮,你可以使用我做的这个类别:

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

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

 #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];

答案 3 :(得分:4)

  

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

相反,考虑到Anomie说的话,你可以这样做:

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

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

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

答案 4 :(得分: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”。希望这会有所帮助。