2011-03-12 121 views

回答

11

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

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

它绕过需要添加用户信息,因为你把你的点击handeling功能直接进入警报状态。例如

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

xcode崩溃无法识别的选择器? – Lunayo 2012-04-04 10:20:42

+0

您是否从链接下载了UIAlertView + Blocks.h,其中包含'#import UIAlertView + Blocks.h'这一行? – Robert 2012-04-04 19:48:41

+0

是的,我已经添加了。我已经解决了制作新类而不是将UIAlerView + Blocks.h添加到项目的问题 – Lunayo 2012-04-05 08:26:28

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

+0

谢谢@Anomie!这是我的代码:' - (void)setObject:(id)object {objc_setAssociatedObject(self,&fooKey,object,OBJC_ASSOCIATION_RETAIN); } - (id)object { return objc_getAssociatedObject(self,&fooKey); } ' – aLt 2011-03-12 15:07:48

+0

这很酷。它适用于我,如果我给它一个字面上的C字符串,如“键”,而不是创建一个静态字符,因为我正在做的全部点是避免创建全局/类变量(其中userInfo可以去)是否可以安全地假设两个相同的c字符串文字将指向相同的内存位置? – 2011-04-27 09:51:26

+3

@ZakyGerman:不完全安全。 C标准(Objective-C基于此标准)说:“只要它们的元素具有适当的值,就不明确[字符串文字的字符数组]是否不同。”这意味着它允许编译器将所有''key''实例指向同一个内存位置,或者全部指向不同的位置或两者中的一些。 – Anomie 2011-04-27 10:54:16

4

它的工作对我来说,如果我给它一个文字C字符串,如“钥匙”,而不是创建一个静态的字符

相反,考虑到什么失范说,你可以不是这样做:

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

这适用于任何事情,它允许你使用任意无效*(观察,此功能等),不需要额外的静态变量技巧。而且,无论编译器做什么,(const void *)0x314都是0x314。

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

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)。当字典被释放时,字典在对象被释放并且字典的对象被释放时被释放。苹果公司如此简单让人惊叹。

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

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

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

+1

+1优雅的方法 – 2013-04-26 22:06:23

+0

不错。我将我的类别命名为** arbitraryobjectonanynsobjectlol **。啊... obj-c命名空间冲突... http:// stackoverflow。com/a/1021040/129202 – Jonny 2014-02-21 03:18:00

+0

我无法以这种方式添加关联对象到'NSDate'对象,并创建了一个关于它的新的SO问题:http://stackoverflow.com/questions/30308082/how-to-make- nsdate-with-associative-object-work – vomako 2015-05-18 16:14:53

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”。希望这可以帮助。

相关问题