2011-03-12 122 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」。希望這可以幫助。

相關問題