2010-01-19 66 views
4

我是新來的objective-c並且遇到問題。是否有可能將某個函數的參數用作某些變量名稱?例如,假設我有一堆圖像:aPic1,aPic2,bPic1,bPic2,cPic1,cPic2,並且我想創建一個動作,以便每次點擊一個按鈕時,視圖控制器都會隱藏Pic1並顯示Pic2,具體取決於點擊哪個按鈕。使用參數作爲變量名稱在objective-c

- (void) performAction:(NSMutableString *) text 
{ 
    [text appendString:@"Pic1"].hidden = YES; //I wanna hide textPic1, which is a UIImageView 
    [text appendString:@"Pic2"].hidden = NO;  //I wanna show textPic2, which is also a UIImageView 
} 

我知道我不應該在這種情況下使用NSString或NSMutableString。任何人都有任何想法如何我可以用這種功能實現我的目標?謝謝。

+0

一個提醒:不要忘記請將有用的答案標記爲有用,並將其作爲您的問題所接受的最有用的答案 – 2010-01-20 13:41:02

回答

5

當然可以。 (c):)

對於我建議工作的解決方案,您需要能夠通過方法訪問(設置/獲取)變量(很容易使用屬性或編寫自己的setters和getters)。

下面是一個例子:

- (void)performAction:(NSMutableString *)text { 
    [(UIImageView *)[self performSelector:NSSelectorFromString([text stringByAppendingString:@"Pic1"])] setHidden:YES]; 
    [(UIImageView *)[self performSelector:NSSelectorFromString([text stringByAppendingString:@"Pic2"])] setHidden:NO]; 
} 

至於我其實想過只是給你一個示例代碼使用Objective-C的這一大特點儘快,我會做得到啓動性能。雖然我不確定要深入討論這個主題,因爲它可能需要太多的互聯網文件,所以這就是爲什麼在示例代碼之後,我還會添加一些鏈接以供進一步閱讀。

@interface AClass : NSObject { 
    // Here's where you declare variables 
    NSObject *objectForInternalUseWeWantToBeRetained; 
    id linkToObjectUsuallyNotRetained; 
    int nonObjectVariable; 
    BOOL aVariableWithARenamedGetter; 
} 

// And here's where their properties are declared 
@property (nonatomic, retain) NSObject *objectForInternalUseWeWantToBeRetained; 
@property (nonatomic) id linkToObjectUsuallyNotRetained; 
@property (nonatomic, assign) int nonObjectVariable; 
@property (nonatomic, assign, getter=renamedVariableGetter) BOOL aVariableWithARenamedGetter; 


@end 


@implementation AClass 

// Here we command the machine to generate getters/setters for these properties automagically 
@synthesize objectForInternalUseWeWantToBeRetained, linkToObjectUsuallyNotRetained, nonObjectVariable, aVariableWithARenamedGetter; 

// But you can implement any of the getters/setters by yourself to add some additional behaviour 
- (NSObject *)objectForInternalUseWeWantToBeRetained { 
    // Some additional non-usual stuff here 

    // And after that we do the getters job - return the variables value 
    return objectForInternalUseWeWantToBeRetained; 
} 

// And of course we don't forget to release all the objects we retained on dealloc 
- (void)dealloc { 
    [objectForInternalUseWeWantToBeRetained release]; 

    [super dealloc]; 
} 


@end 

// And here's where their properties are declared 
@property (nonatomic, retain) UIImageView *testPic1; 
@property (nonatomic, retain) UIImageView *testPic2; 


@end 

警告:我非常快速地跑完了足部。 Here's a nice tutorial at CocoaCast blog - Properties in Objective-C 2.0,我認爲這可能是一個很好的起點。順便說一句,他們提供了大量的學習資料(播客,屏幕錄像等),因此進一步瀏覽他們的網站可能會有用。當然,學習Objective-C和Cocoa的主要地方是官方文檔here's where it is about properties

+1

'valueForKey:'做同樣的事情;) – 2010-01-19 15:46:15

+0

但是我第一次! :D有很多方法可以做到這一點......我們甚至沒有提到通過NSInvocation獲得相同的結果。 o_O – 2010-01-19 15:53:50

+0

感謝Ivan的幫助。這解決了我的問題。但正如你所說的聲明屬性,我一直想知道如何選擇正確的屬性來聲明我的每個變量。(很明顯,我的閱讀是嚴重不足的:p)感謝你能給我一些指導。謝謝。 – Anthony 2010-01-19 16:31:48

1

你可以存儲在字典中的所有子視圖:

NSMutableDictionary *viewsByName = [[NSMutableDictionary alloc] init]; 

[viewsByName addObject:aPic1 withKey:@"aPic1"]; 
[viewsByName addObject:aPic2 withKey:@"aPic2"]; 
[viewsByName addObject:bPic1 withKey:@"bPic1"]; 
[viewsByName addObject:bPic2 withKey:@"bPic2"]; 

然後:

- (void) performAction:(NSString *) text 
{ 
    ((UIView *)[viewsByName objectWithKey:[NSString stringWithFormat:@"%sPic1",text]]).hidden = YES; 
    ((UIView *)[viewsByName objectWithKey:[NSString stringWithFormat:@"%sPic2",text]]).hidden = NO; 
} 
+0

如果沒有人不介意,幾乎沒有什麼補充。 至於使用標籤 - 最好不要使用實際的數字,而是定義標籤的常量(即TAG_IMAGEVIEW_PIC1)。 至於使用字典 - 最好不要使用可變字典來存儲不可變的數據;另一個重要的事情是不要忘記在viewDidUnload和視圖中釋放這個字典。 – 2010-01-19 15:50:44

3

這是可能的,但以迂迴的方式。您可以使高德@properties你的類,然後通過訪問它們:

id myIvar = [self valueForKey:[text appendString:@"Pic1"]]; 
[myIvar setHidden:YES]; 

或者你可以在運行時走低,並使用這些方法:

#import <objc/runtime.h> 

id myIvarValue = nil; 
[text appendString:@"Pic1"]; 
Ivar theIvar = object_getInstanceVariable(self, [text UTF8String], &myIvarValue]; 
[myIvarValue setHidden:YES]; 
相關問題