【问题标题】:How to differentiate the returned value of a function using completion block in Objective C?如何使用Objective C中的完成块区分函数的返回值?
【发布时间】:2018-06-29 16:12:59
【问题描述】:

我有一个函数可以返回 2 个不同的字符串值:

-(NSString*)load:(NSDictionary *)dict
{

    NSDictionary *dataDict = [self objectForId:@"data" fromDict:dict withDefault:nil];
    if (dataDict) {
        NSDictionary *success = [self objectForId:@"success" fromDict:dataDict withDefault:nil];

        NSString *str = [NSString stringWithFormat:@"%@", success];

        if ([str isEqualToString: @"1"])
        {
            NSDictionary *idDict = [self objectForId:@"id" fromDict:dataDict withDefault:nil];
            if (idDict) {
                NSString *idString = [NSString stringWithFormat:@"%@", idDict];
                return idString;
            }

        } else {
            NSDictionary *messages = [self objectForId:@"messages" fromDict:dataDict withDefault:nil];
            if (messages) {
                NSDictionary *messageDict = (NSDictionary *)messages;
                NSArray *type = messageDict[@"type"];
                if (type.count > 0) {
                    NSString *messageString = type[0][@"message"];
                    return messageString;
                }
            }
        }
    }
    return  nil;
}

并像这样访问 stringValue:

 NSString *string = [className load:dict];

现在我想为“idString”和“messageString”返回值编写 if else 语句。如何区分这 2 个返回值?

【问题讨论】:

  • 你想知道在线NSString *string = [className load:dict];,如果string来自成功或“id”或“消息”键?为此使用块怎么样?还是返回字典?或者使用两个点指针(-(void)load:(NSDictionary *) dict key:(NSString **)key value:(NSString **)value),并用[className load:dict key:&someString value:&string]调用它?
  • @Larme 如何使用完成块返回值?

标签: objective-c if-statement nsstring return-value objective-c-blocks


【解决方案1】:

虽然返回 NSDictionary(参见 @Yihui Yang solution)或自定义类(参见 @Sulthan's solution)是有效的解决方案,但它可能太多了。
您需要记住返回的字典的键,或者为此创建一个自定义类太多了。

这里有另外两种可能性:

我会有样本字典来测试:

NSDictionary *dictToTest1 = @{@"id": @"idString",
                              @"noiseKey": @"noiseValue"
                              };
NSDictionary *dictToTest2 = @{@"messages": @"messagesString",
                              @"noiseKey": @"noiseValue"
                              };

我将简化您的测试,仅检查键 idmessages 是否存在键/值。

使用双指针:

-(void)loadDict:(NSDictionary *)dict withRetKey:(NSString **)key andRetValue:(NSString **)value
{
    NSString *retKey = nil;
    NSString *retValue = nil;
    if (dict[@"id"])
    {
        retKey = @"id";
        retValue = dict[@"id"];
    }
    else if (dict[@"messages"])
    {
        retKey = @"messages";
        retValue = dict[@"messages"];
    }

    if (key)
    {
        *key = retKey;
    }

    if (value)
    {
        *value = retValue;
    }
}

样本测试:

NSString *key1 = nil;
NSString *value1 = nil;
[self loadDict:dictToTest1 withRetKey:&key1 andRetValue:&value1];
NSLog(@"Key1: %@\t value1: %@", key1, value1);
NSString *key2 = nil;
NSString *value2 = nil;
[self loadDict:dictToTest2 withRetKey:&key2 andRetValue:&value2];
NSLog(@"Key2: %@\t value2: %@", key2, value2);

输出:

$> Key1: id  value1: idString
$> Key2: messages    value2: messagesString

您在哪里看到对象的 &
几乎所有时间都在管理NSError。 (linked question)
对于原始人?例如,如果您想检索 UIColor (linked question) 的红色/蓝色/绿色/alpha 值

有块:

-(void)blockLoadDict:(NSDictionary *)dict withBlock:(void(^) (NSString *key, NSString *value))block
{
    NSString *retKey = @"";
    NSString *retValue = @"";
    if (dict[@"id"])
    {
        retKey = @"id";
        retValue = dict[@"id"];
    }
    else if (dict[@"messages"])
    {
        retKey = @"messages";
        retValue = dict[@"messages"];
    }

    if (block)
    {
        block(retKey, retValue);
    }
}

示例:

__block NSString *key3 = nil;
__block NSString *value3 = nil;
[self blockLoadDict:dictToTest1 withBlock:^(NSString *key, NSString *value) {
    key3 = key;
    value3 = value;
}];
NSLog(@"Block Key3: %@\t value3: %@", key3, value3);

__block NSString *key4 = nil;
__block NSString *value4 = nil;
[self blockLoadDict:dictToTest2 withBlock:^(NSString *key, NSString *value) {
    key4 = key;
    value4 = value;
}];
NSLog(@"Block Key4: %@\t value4: %@", key4, value4);

输出:

$> Block Key3: id    value3: idString
$> Block Key4: messages  value4: messagesString

【讨论】:

    【解决方案2】:

    我的理解是你想知道load方法返回的是idString还是messageString。

    所以我建议使用一种棘手的方法。

    您可以返回一个类似的字典,而不是返回一个字符串

        return @{
             @"type":@"idString",
             @"content":idString
             }
    

    并使用

    NSDictionary * returnDict = [className load:dict]
    if ([returnDict[@"type"] isEqualToString:@"idString"]) {
        //code here
    }
    else{
        //code here
    }
    

    最后,我知道这不是最好的解决方案,但它可以正常工作。

    【讨论】:

      【解决方案3】:

      我会制作两种不同的方法。第一个只会返回 id 字符串,第二个会返回一条消息。

      这样你就可以做出这样的事情:

      NSDictionary *dict = /* some code here */;
      NSString *message = nil;
      NSString *idString = [foo loadId:dict];
      if (idString.length == 0) {
          message = [foo loadMessage:dict];
      }
      

      【讨论】:

        【解决方案4】:

        创建一个将返回的对象,而不是返回一个简单的字符串:

        @interface Result: NSObject
        @property (nonatomic) NSString *id;
        @property (nonatomic) NSString *message;
        @end
        

        理想情况下,您可以创建处理解析的 -initWithDictionary: 初始化程序。

        【讨论】:

          【解决方案5】:

          您可以使用 NSException。而不是返回 idString 你抛出一个 NSException

          @throw [NSException exceptionWithName:idString reason:nil userInfo:nil];
          

          然后你可以这样调用你的方法:

          @try{
              NSString *messageString = [className load:dict];
              NSLog(@"Message String: %@", messageString);
          }@catch (NSException *e){
              NSString * idString = e.name;
              NSLog(@"ID String: %@",idString);
          }
          

          【讨论】:

          • 这是一个非常糟糕的主意。 Objective-C 中的异常是非常昂贵的。它们应该只用于实际的异常。它不应该用于区分返回值中的数据。
          • 知道异常是昂贵的,但我不能采取任何其他方式来做到这一点并保持方法返回 NSString。也许如果有某种模式 id 字符串与消息字符串有何不同,您可以检查该字符串。例如检查字符串是否包含 n 个数字,但消息字符串可以以相同的方式再次组成
          • @najdanovicivan 如果您愿意,可以查看我的回答。我还链接了其他两个答案,列出了 4 种这样做的方法。他们不会“直接”返回NSString(意味着它不是-(NSString *)method),但他们是其他方式......
          • 你给出的答案与我将如何做最相似。但我会为 retKey 使用 bool 值,因为那里只有两个可能的值。我刚刚回答了如何保留 -(NSString *) 方法。我知道例外是昂贵的。但我只是看不到任何其他方法可以做到这一点并保持方法不变
          猜你喜欢
          • 1970-01-01
          • 2017-05-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多