【问题标题】:Check if JSON value exists - iOS检查 JSON 值是否存在 - iOS
【发布时间】:2014-02-27 16:38:55
【问题描述】:

我有一个 iOS 应用程序,它下载并解析 Twitter JSON 提要,然后将该提要呈现在 UITableView 中。这一切都很好,但我有一个问题:

当用户点击 UITableView 单元格时,应用程序将查看数组“tweets_links”并查看该特定推文是否具有附加 URL,如果有,则将显示 Web 视图。

因为并非所有推文都有网站 URL,所以我添加了一个简单的 try catch 语句(就像在 C++ 中一样),它可以告诉我在尝试访问数组的那部分时是否有异常。

我的问题是:这样做是好还是坏??

这是我的代码:

int storyIndex = indexPath.row;
int url_test = 1;
NSString *url;

@try {
    url = [[tweets_links[storyIndex] valueForKey:@"url"] objectAtIndex:0];
}

@catch (NSException *problem) {
    // There is NO URL to access for this Tweet. Therefore we get the out of bounds error.
    // We will NOT take the user to the web browser page.
    // Uncomment the line below if you wish to see the out of bounds exception.
    // NSLog(@"%@", problem);
    url_test = 0;
}

if (url_test == 1) {
    WebBrowser *screen = [[WebBrowser alloc] initWithNibName:nil bundle:nil];
    self.seconddata = screen;
    seconddata.web_url = url;
    screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self presentViewController:screen animated:YES completion:nil];
}

else if (url_test == 0) {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Info" message:@"There is no URL attatched to this Tweet." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [alertView show];

    [tweetTableView deselectRowAtIndexPath:indexPath animated:YES];
}

有没有更好的方法来尝试实现我正在做的事情???

谢谢,丹。

【问题讨论】:

  • 应该不需要try-catch。当您向 NSDictionary 询问不存在的条目时,它会返回 nil,您可以轻松地对其进行测试。 (事实上​​,你必须非常努力才能获得例外。)
  • 不要使用valueForKey:,使用objectForKey:
  • 因为 valueForKey: 是一个高度复杂的方法,可以为各种不同的对象处理各种关键路径,所以它必须仔细检查路径是什么,该方法发送的对象是什么to 等等,而 objectForKey 仅用于在字典中查找内容。可能跑得快十倍。

标签: ios objective-c json uitableview try-catch


【解决方案1】:

不鼓励使用 try 和 catch 是 Objective-C 不鼓励检查和处理错误的其他方法

// firstObject will return the first object in the array or nil if the array is empty.
url = [[tweets_links[storyIndex][@"url"]] firstObject];

if (!url) {
    // handle the case for no url
} else {
    // do something with url
}

由于向nil 发送消息在Objective-C 中是安全的并返回nil,因此链式调用是安全的。例如如果字典没有该键的对象,那么它将返回 nil 并将 firstObject 发送到 nil 返回 nil

【讨论】:

  • 当您不太清楚自己在做什么时,链接调用是不明智的。使调试更加困难。
  • @HotLicks 确实如此。但是,如果您正在处理可能包含或不包含数据的 JSON 响应,并且您可以明智地处理不存在的数据,那么可以说尝试它并处理 nil 响应会更容易。我从 Haskell 和 Maybe monad 那里学到的东西。
  • 但尤其是对于新手来说,一长串的调用令人困惑,难以区分,因此无法理解。打断链条没有坏处——没有性能损失,也没有功能损失。
  • @hotlicks。我同意。但并不是每个人都想要一个新手级别的答案。
  • 但是我已经编程 40 年了,我也不喜欢长链。太难理解和调试了。
【解决方案2】:

如果以下方法都可以,则使用其中之一,因为 TRY CATCH 用于捕获编程错误 并使用 objectForKey: 代替 valueForKey

if ([tweets_links[storyIndex] objectForKey:@"url"] != nil)

if ([url isKindOfClass:[NSString class]])
{
// Code handling the URL
}
else
{
// Code handling there is no URL
}

【讨论】:

    【解决方案3】:

    我对 Twitter 提要知之甚少,但您可能可以像这样检查从 objectForKey: 返回的 nil

    if ([tweets_links[storyIndex] objectForKey:@"url"] != nil) { /* process the URL */ }
    

    您的代码假定该值始终是一个至少 size = 1 的数组,在假定它是一个数组之前检查 @"url" 键的值会更安全。

    【讨论】:

      【解决方案4】:

      在 Objective-C 中使用异常被抛出。异常是为编程错误保留的。你没有抓住他们,你修复了代码。使用 JSON 文档,您永远无法保证收到的内容,所以请小心。

      NSString* url = nil;
      NSArray* linksArray = nil;
      NSDictionary* linkDict = nil;
      NSArray* urlArray = nil;
      
      if ([tweet_links isKindOfClass:[NSArray class]])
          linksArray = tweet_links;
      
      if (storyIndex >= 0 && storyIndex < linksArray.count)
          linkDict = linksArray [storyIndex];
      
      urlArray = linkDict [@"url"];
      if ([urlArray isKindOfClass:[NSArray class]] && urlArray.count > 0)
          url = urlArray [0];
      
      if ([url isKindOfClass:[NSString class]])
      {
          // Code handling the URL
      }
      else
      {
          // Code handling there is no URL
      }
      

      请注意,向 nil 对象发送消息始终会根据需要返回 0 / NO / nil。

      请养成正确命名变量的习惯。你写了“int url_test = 1;”。 url_test 是什么意思?我读了变量名,我不知道它是什么意思。我需要理解所有代码。将其设为“int”意味着它可以是 0、1、2、20000 或其他任何值。如果你改为写“BOOL urlValid = YES;”很清楚:这意味着您有一个有效的 URL。

      【讨论】:

        【解决方案5】:

        由于 url 值是一个 NSString 值,你可以使用length 来检查它是否为 nil,如果不是,它是否有任何值(不是空字符串)。然后你可以检查这个 NSString 是否是一个有效的 url。

          - (BOOL) validateUrl: (NSString *) candidate {
                NSString *urlRegEx = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
                NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; 
                return [urlTest evaluateWithObject:candidate];
            }
        

        ....

        NSString *url = [[tweets_links[storyIndex][@"url"]] firstObject];
        
        if ([url length] && [self validateUrl: url]) {
         // Has a valid URL
        }
        

        【讨论】:

        • 非空字符串不是有效的 url。最好尝试使用 URL 并处理任何错误,而不是采用这种简单的方法。
        • 好吧,在这种情况下,您可以使用 validate 方法来检查 url 字符串。请参阅编辑的答案! :)
        猜你喜欢
        • 2012-06-23
        • 2017-03-17
        • 2022-07-12
        • 1970-01-01
        • 1970-01-01
        • 2020-03-22
        • 2015-10-09
        • 2015-07-08
        • 1970-01-01
        相关资源
        最近更新 更多