簡體   English   中英

從Objective-C中的方法返回多個值

[英]Returning multiple values from a method in Objective-C

我問了一個類似的問題,但我無法讓它完全正常工作。 我正在構建一個iPhone應用程序,我想從不同的文件中調用一個方法。 我認為最簡單的方法就是在另一個文件中創建一個方法,並從其他文件中調用該方法。

這是一些問題。 我需要在傳遞多個值后從該方法返回多個值。 例如,我傳遞它: (int, int, int, string, string) 並且它們需要在更改后返回所有這些值。 有人給我看了這段代碼:

- (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness
{
    varTurns--;

    if (varTurns <= 0) {
        varFatness = varFatness - 5;
    }
    else {
        varFatness += 2;
    }

    return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:varFatness], @"FATNESS", [NSNumber numberWithInt:varTurns], @"TURNS", nil];

}

但是,此代碼不起作用,我需要更多信息才能真正理解它。 讓我們假設我傳遞了這些值:

int varMoney;
int varNumSheep;
int varNumShepherds;
NSString *test1;
NSString *test2;

所以我需要從方法中獲取所有這些值。

如何在頭文件中聲明這個? 這應該是一個Objective-C的文件,但你可以給我的代碼整個文件,所以我可以看到哪里會與去@implementation@end ,諸如此類的東西。 另外,我怎么稱呼這種方法?

如何將值作為指針傳遞?

例如:

- (void) getValuesForInt:(int *)int1 anotherInt:(int *)int2 aBool:(BOOL *)bool1 anotherBool:(BOOL *)bool2 {
  if (*int1 == 42 && *int2 == 0) {
    *int1 = 0;
    *int2 = 42;
  }
  if (*bool1 == NO) {
    *bool2 = YES;
  }
}

然后你可以調用它:

int int1 = 42;
int int2 = 0;
BOOL bool1 = NO;
BOOL bool2 = NO;
[self getValuesForInt:&int1 anotherInt:&int2 aBool:&bool1 anotherBool:&bool2];
NSLog(@"int1: %d int2: %d bool1: %d bool2: %d", int1, int2, bool1, bool2);
//prints "int1: 0 int2: 42 bool1: 0 bool2: 1"

編輯:

這同樣適用於對象。 在處理NSError對象時,您經常會看到這種情況:

NSError *error = nil;
[anObject doSomething:foo error:&error];

可以實現為:

- (void) doSomething:(id)terrible error:(NSError **)error {
  if ([terrible isEqual:reallyBad]) {
    if (error != nil) { *error = [NSError errorWithDomain:@"domain" code:42 userInfo:nil]; }
  }
}

如果您需要從方法返回許多不同的東西,請將其封裝到NSDictionary中,就像其他人建議的那樣,或者只考慮定義一個類。 您可以根據需要聲明實例變量和屬性以封裝數據。

定義用於封裝此類信息的類證明非常有效並且最大化靈活性。 如果您需要重構您的應用程序,使得數據集合獲得新字段,需要保存以供日后使用,或者可能需要獲得功能,那么類將簡化這些更改。

您可以使用塊閉包從這樣的方法傳回多個值。 -rrh

[self heyFunctionGiveMeBackTwoValuesFromThisFruitArray:@[@"apple", @"orange", @"banana", @"apple"] findThisFruit:@"apple" closureFunction:^(int fruitCount, NSString* fruitString)
{
    NSLog(@"Two values returned, int-fruitCount:%d, NSString-fruiteString:%@", fruitCount, fruitString);
}];

- (void)heyFunctionGiveMeBackTwoValuesFromThisFruitArray:(NSArray*)fruitsArray findThisFruit:(NSString*)findThisFruit closureFunction:(void (^)(int fruitCount, NSString *fruitString))passBackResultsUsingThisClosure
{
    NSInteger fruitsFound = 0;
    NSString* fruitsMessage = [NSString stringWithFormat:@"No %@ Found", findThisFruit];
    for (NSString* string in fruitsArray)
    {
        if ([string compare:findThisFruit] == NSOrderedSame)
        {
            fruitsFound++;
        }
    }
    if (fruitsFound > 0)
    {
        fruitsMessage = [NSString stringWithFormat:@"You have %@ on your list this many times:%d", findThisFruit, fruitsFound];
    }
    passBackResultsUsingThisClosure(fruitsFound, fruitsMessage);
}

結果:返回了兩個值,int-fruitCount:2,NSString-fruiteString:你的列表中有多次蘋果:2

由於您只能從C和C派生語言中的任何方法返回單個值,因此您只需返回表示所有其他值的單個值。 這是您的示例代碼使用NSDictionary

示例代碼是正確的,即使它與常見的Objective-C樣式有點相反。

你在頭文件中聲明的只是方法的聲明,即:

@interface MyClass : NSObject
- (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness;
@end

在源文件中,然后:

@implementation MyClass
// code, as given above
@end

如果您只需要返回原始值,那么返回結構可能是最佳解決方案。 您將獲得編譯時錯誤檢查(例如,與您可能嘗試讀取無效密鑰的NSDictionary相反),同時不需要創建類所涉及的所有代碼/文件。

typedef struct myStruct {
  int varMoney;
  int varNumSheep;
  int varNumShepherds;
} myStruct;

Apple也在其許多方法中使用結構(例如CGPoint,CGRect)。

這不適用於對象的原因是因為ARC禁止這樣做

對某些設計中的最后一點稍微改進的是使用包含枚舉成員的結構。 這為您提供了已經提到的編譯時檢查,它看起來像返回值中的對象,如果您需要檢查返回值中的值,則可以獲得明確的情況。

結構:

typedef struct _SIXRecorderStateChange {
    SIXRecorderState oldState;
    SIXRecorderState newState;
} SIXRecorderStateChange;

客戶端代碼:

    SIXRecorderStateChange stateChange = [recorderState stop];
    if (stateChange.newState == SIXRecorderStopped) {
...
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM