Iphone 从Objective-C中的方法返回多个值
我问了一个类似的问题,但我不能让它完全正常工作。我正在构建一个iPhone应用程序,我想从不同的文件调用一个方法。我认为最简单的方法就是在另一个文件中创建一个方法,然后从其他文件中调用该方法 这里有一些问题。在传递多个值之后,我需要从方法返回多个值。例如,我正在传递它:Iphone 从Objective-C中的方法返回多个值,iphone,objective-c,return-value,Iphone,Objective C,Return Value,我问了一个类似的问题,但我不能让它完全正常工作。我正在构建一个iPhone应用程序,我想从不同的文件调用一个方法。我认为最简单的方法就是在另一个文件中创建一个方法,然后从其他文件中调用该方法 这里有一些问题。在传递多个值之后,我需要从方法返回多个值。例如,我正在传递它:(int,int,int,string,string)。它需要在这些值被更改后返回所有这些值。有人给我看了这个代码: - (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(i
(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];
}
所以我需要从方法中得到所有这些值
我如何在头文件中声明它?这应该在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]; }
}
}
由于您只能从C和C派生语言中的任何方法返回一个值,因此只需返回一个表示所有其他值的值。这就是示例代码使用
NSDictionary
所做的
示例代码是正确的,即使它有点与常见的Objective-C风格相反
您在头文件中声明的只是方法的声明,即:
@interface MyClass : NSObject
- (NSDictionary *)EndOfTurn:(int)varTurns withFatness:(int)varFatness;
@end
在源文件中,然后:
@implementation MyClass
// code, as given above
@end
如果你有很多不同的东西需要从一个方法中返回,或者把它封装成一个NS字典,就像其他人建议的那样,或者只是定义一个类。您可以根据需要声明实例变量和属性来封装数据
事实证明,定义一个类来封装这些信息是非常有效的,并且可以最大限度地提高灵活性。如果您需要重构应用程序,使数据集合获得新字段、需要保存以备将来使用,或者可能需要获得功能,则类将简化这些更改。如果您只需要返回基本值,则返回结构可能是最佳解决方案。您可以进行编译时错误检查(例如,与NSDictionary相反,在NSDictionary中,您可以尝试读取无效密钥),同时不需要创建类所涉及的所有代码/文件
typedef struct myStruct {
int varMoney;
int varNumSheep;
int varNumShepherds;
} myStruct;
苹果在许多方法中也使用了结构(例如CGPoint、CGRect)
这不适用于对象的原因是。在某些设计中,对最后一点的一个小小改进是使用包含枚举成员的结构。这为您提供了前面提到的编译时检查、返回值中看起来像对象的东西,以及如果需要检查返回值中的值,则清除大小写的好处 结构:
typedef struct _SIXRecorderStateChange {
SIXRecorderState oldState;
SIXRecorderState newState;
} SIXRecorderStateChange;
客户端代码:
SIXRecorderStateChange stateChange = [recorderState stop];
if (stateChange.newState == SIXRecorderStopped) {
...
...
可以使用块闭包从这样的方法传回多个值-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-fructCount:2,NSString-fructestring:apple多次出现在您的列表中:2我想指出的是,“withFatness”是一个非常棒的函数。您还需要保留此函数的结果。因为您返回的词典是通过一种方便的方法生成的,所以它会自动删除,如果不保留,很快就会消失。i、 e.当你叫它时,你会这样做:NSDictionary*myDic=[self EndOfTurn:turns with fatness:fatness];[保留多年电价];然后[myDic释放];当你做的很好并且完成了它。它应该是*int2==0。另外,您的NSLog行缺少参数。@Wayfarer edit answer提供了一个如何处理对象的示例。我对该方法的不满是,不能传入属性,因为作为属性的参数可能甚至没有底层内存位置,因此该语言禁止这样做。这意味着,除了在不需要返回时频繁传递nils之外,如果任何辅助值需要存储在属性中,则需要首先声明一个局部变量,然后将该值分配给属性。好的,调用此函数的语法是什么?我已经导入了头文件,但是当我尝试调用函数时,它会说“Expected:Before:token.This调用:(NSDictionary*)EndOfTurn:(int)varTurns withFatness:(int)varFatness;我将变量“varTurns”和“varFatness”传递给它,您的调用应该类似于[object EndOfTurn:varTurns withFatness:varFatness](int)bits只是用于定义,而不是调用。我很确定,自ARC以来,不再支持在struct中嵌入对象。可能最好像其他人提到的那样使用类或字典,即使它稍微不太“优化”“。如果您不担心工作负载,尤其是对帧敏感的应用程序,这将是一个好主意。如果你正在开发,比如说一款虚拟现实应用,每一点节省都会带来好处,所以我个人会在这些情况下使用DaveDeLong的答案。
[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);
}