2016-11-24 63 views
0

我有非常非常奇怪的事情。 在我简单的函数中,我创建了包含设置参数字典的变量。它被设置为'let',所以内部循环只是读取它。 在循环时间的随机时刻,它会以“未解决的设置”崩溃。 看起来像smth使它成为零。谁做的?Swift 3变量自我删除

private static func preferencesFilter(userIDs: [Int], access: String) -> [User] { 
    self.sharedInstance.delegate?.updateActionLabel(label: "Filter") 
    var result = [VKUser]() 
    let settings = self.parseSettings() 
    let progressFraction = 1.00/Float(userIDs.count) 
    var n = 0 
    for userID in userIDs { 
     if sharedInstance.stopped { 
      return [] 
     } 
     n += 1 
     let user = VKUser.getUser(id: userID, access_token: access_token) 
     if settings["gender"] != nil { 
      if user.sex == settings["gender"] as! String { 
       if (user.born?.isBetweeen(date1: settings["minAge"] as! Date, date2: settings["maxAge"] as! Date))! { 
        if settings["country"] != nil { 
         if user.country == settings["country"] as! String { 
          result.append(user) 
         } 
        } 
        else { 
         result.append(user) 
        } 
       } 
      } 
     } 
     else { 
      if (user.born?.isBetweeen(date1: settings["minAge"] as! Date, date2: settings["maxAge"] as! Date))! { 
       if settings["country"] != nil { 
        if user.country == settings["country"] as! String { 
         result.append(user) 
        } 
       } 
       else { 
        result.append(user) 
       } 
      } 
     } 
     self.sharedInstance.delegate?.updateProgress(value: Float(n) * progressFraction) 
    } 
    return result 
} 
+0

我想你真的写了很多不安全的代码。尝试添加一些“如果让”组合或“警卫”,以使其更安全。尽量不要强制施放任何东西(用“!”),最终会导致程序崩溃。 我试图将它改写成更快捷和更安全的东西,但即使如此,在所有if-else语句和跳过的案例中都迷失了方向。你是否写过任何单元测试来检查这个方法是否正在做你想要的东西?有很多组合可以或不会追加用户。 – Jelle

+0

@Jelle谢谢你的回答!你的意思是说这本词典有错误吗?但如果它是静态的,它会是怎样的错误。它只是加载到内存中(正如我理解的那样)。我不会动态更新它。它是不是“垃圾收集器”错误的工作? '因为如果我会做“守卫”,那只会意味着它没有错误,脚本工作不正确。 –

+0

我的意思是代码难以阅读,并可能在实际情况下崩溃。我会尝试将它改写成更稳定的东西......坚持下去。 – Jelle

回答

0

我重构你的代码为更迅速,如:

private static func preferencesFilter(userIDs: [Int], access_token: String) -> [User]? { 
    guard userIDs.count > 0 else { 
     return [User]() // no input, return empty list 
    } 
    let settings = self.parseSettings() 
    guard let minAge = settings["minAge"] as? Date, 
     let maxAge = settings["maxAge"] as? Date 
     else { 
      return nil 
    } 
    let country = settings["country"] as? String // specified or nil 
    let gender = settings["gender"] as? String  // specified or nil 

    sharedInstance.delegate?.updateActionLabel(label: "Filter") 
    var result = [VKUser]() 
    let progressFraction = 1.00/Float(userIDs.count) 
    var n = 0 
    for userID in userIDs { 
     if !sharedInstance.stopped { 
      n += 1 
      let user = VKUser.getUser(id: userID, access_token: access_token) 
      var shouldInclude = true 

      if user.sex != gender { // wrong sex or no required gender specified 
       shouldInclude = false 
      } 
      if user.country != country { // wrong country or no required country specified 
       shouldInclude = false 
      } 
      if let born = user.born { 
       if !born.isBetweeen(date1: minAge, date2: maxAge) { 
        shouldInclude = false 
       } 
      } else { // no user.born date, cant check if in range 
       shouldInclude = false 
      } 

      if shouldInclude { 
       result.append(user) 
      } 
      sharedInstance.delegate?.updateProgress(value: Float(n) * progressFraction) 
     } 
    } 
    return result 
} 

这是你打算写?这是如何为你跑? 你可以改变这是一个非静态的方法吗?对我更有意义。 您可以看到它现在返回一个可选项,因为该方法可能会失败,并且为零。你的调用代码应该正确处理。

+0

它的工作原理!事实上,我看到它更简单易读,但为什么我的“肮脏”版本崩溃对我来说是未知的。在这里,我们只是检查零,这是否意味着在某些情况下,它可能会被删除,我们不会看到它发生?如果我们几乎不打开包装,我们只是丢失一些数据? –

+0

我花了一段时间来破译你的代码,所以它可能包含一些有趣的隐藏错误。为了检查真正的问题,我需要运行真实的代码并进行调试。也许现在解决了代表的副作用。也许别的东西是错的。至少现在的代码很容易阅读和理解,所以发现错误也应该更容易。 在这段代码中,如何处理nil值有几种方法:一些需要非可选项(来自设置的minAge和maxAge),一些如果为零(国家,性别)和可选的“天生”属性则被忽略的真实可选项。 – Jelle

+0

一些小的评论:我会将minAge和maxAge更改为更好的名称,因为它们不是“年龄”值,而是日期。 “出生”也不是我想用的名字,生日可能会更好。当性别和性别都是“性别”时,它们可能更易于阅读。 – Jelle