【问题标题】:Expression was too complex to be solved in reasonable time Swift 3表达式太复杂,无法在合理的时间内解决 Swift 3
【发布时间】:2016-10-01 22:47:54
【问题描述】:

我正在尝试将我的项目转换为 Swift 3,但我收到一条错误消息,指出表达式太复杂,无法在合理的时间内解决。我不知道为什么会这样,因为这个表达式在 Swift 2.2 中运行良好,但现在突然花了这么长时间?

有谁知道我该如何解决这个问题?这是表达式。它基本上是一个字典,稍后将与SecItemCopyMatching 一起使用,以从使用密钥标签保存的钥匙串中提取项目。它执行touchID 来执行此操作,因为它是使用该锁定参数保存的:

let query : [String: AnyObject] = [String(kSecClass) : kSecClassGenericPassword,
     String(kSecAttrService) : keyTag as AnyObject,
     String(kSecAttrAccount) : keyTag,
     String(kSecReturnData) : kCFBooleanTrue,
     String(kSecMatchLimit) : kSecMatchLimitOne,
     String(kSecUseOperationPrompt) : message]

【问题讨论】:

  • 您查看过these search results 的错误信息吗?您可能会发现一些有用的东西。
  • 错误“表达式太复杂,无法在合理时间内解决”高度依赖于上下文。有时完全相同的表达式会在一个上下文中导致错误,而在另一个上下文中不会。您可能需要显示更多代码上下文,至少显示 keyTagmessage 是如何声明的。
  • keyTagmessage 只是字符串。
  • “只是字符串”还不够,StringNSString 还是CFString?所有这些事情都会有所作为。
  • String。但是,接受的答案解决方案修复了它。

标签: ios swift xcode swift3 xcode8


【解决方案1】:

不幸的是,您必须将查询定义为var 并单独分配值。看来 Swift 3.0 无法处理这么长的表达式。

您的代码将如下所示:

var query = [String: AnyObject]()
query[String(kSecClass)] = kSecClassGenericPassword
query[String(kSecAttrService)] =  keyTag as AnyObject
query[String(kSecAttrAccount)] = keyTag
query[String(kSecReturnData)] = kCFBooleanTrue
query[String(kSecMatchLimit)] = kSecMatchLimitOne
query[String(kSecUseOperationPrompt)] = message

【讨论】:

  • 这样你的编译时间也会更短。希望 Swift 团队改进这一点。
【解决方案2】:

尝试将所有字典值转换为AnyObject。除非它们已经是从NSObject 派生的对象(例如NSStringNSNumberNSArrayNSDictionary),否则您需要将它们强制转换为AnyObject。Swift 3 已删除自动桥接到 Foundation 类型。

let query: [String: AnyObject] = [String(kSecClass) : kSecClassGenericPassword as AnyObject,
                                   String(kSecAttrService) : keyTag as AnyObject,
                                   String(kSecAttrAccount) : keyTag as AnyObject,
                                   String(kSecReturnData) : kCFBooleanTrue as AnyObject,
                                   String(kSecMatchLimit) : kSecMatchLimitOne as AnyObject,
                                   String(kSecUseOperationPrompt) : message as AnyObject]

【讨论】:

  • 这似乎也有效。尚未测试,但它消除了错误。谢谢
猜你喜欢
  • 2016-02-21
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
相关资源
最近更新 更多