【问题标题】:High CPU Usage when parsing large json data with Date Strings Swift使用日期字符串 Swift 解析大型 json 数据时 CPU 使用率高
【发布时间】:2020-06-13 13:32:48
【问题描述】:

我正在开发一个聊天应用程序。我得到包含与对话相关数据的对话列表。 Json 响应如下所示

[
  {
    "id": "1021",
    "title": "Test Group",
    "memberCount": 250,
    "isGroup": true,
    "ownerId": "18646",
    "createdAt": "2017-08-24T12:05:06.000Z",
    "type": "private",
    "lastReadAt": {
      "18646": "2020-01-29T06:48:53.700Z",
      "18664": "2020-01-29T07:12:41.613Z",
      "18714": "2020-01-29T07:12:41.613Z",
      // 247 More Records
    },
    "unreadMessageCount": 0,
    "mute": false,
    "isActive": true,
    "isAdmin": true,
    "isDeleted": false,
    "updatedAt": "2020-01-29T07:12:41.124Z",
    "lastMessage": {
      "id": "18a16164-657c-420a-887d-5408f1479619",
      "conversationId": "1021",
      "type": "normal",
      "createdAt": "2020-01-29T07:12:41.124Z",
      "updatedAt": "2020-01-29T07:12:41.124Z",
      "body": "hi",
      "ownerId": "18646",
      "attachments": [],
      "owner": {
          "id": "18646",
          "displayName": "sydney millers",
          "profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
      },
      "mentionedUsers": []
    }
  },
  {
    "id": "1021",
    "title": "Test Group 2",
    "memberCount": 250,
    "isGroup": true,
    "ownerId": "18646",
    "createdAt": "2017-08-24T12:05:06.000Z",
    "type": "private",
    "lastReadAt": {
      "18646": "2020-01-29T06:48:53.700Z",
      "18664": "2020-01-29T07:12:41.613Z",
      "18714": "2020-01-29T07:12:41.613Z",
      // 247 More Records
    },
    "unreadMessageCount": 0,
    "mute": false,
    "isActive": true,
    "isAdmin": true,
    "isDeleted": false,
    "updatedAt": "2020-01-29T07:12:41.124Z",
    "lastMessage": {
      "id": "18a16164-657c-420a-887d-5408f1479619",
      "conversationId": "1021",
      "type": "normal",
      "createdAt": "2020-01-29T07:12:41.124Z",
      "updatedAt": "2020-01-29T07:12:41.124Z",
      "body": "hi",
      "ownerId": "18646",
      "attachments": [],
      "owner": {
          "id": "18646",
          "displayName": "sydney millers",
          "profileImageUrl": "https://sample-file-url/media/fbef1bb47eb85fb2979b135ed04e0eb3.png"
      },
      "mentionedUsers": []
    }
  }
]

lastReadAt 基本上包含群组成员上次阅读对话时的信息。现在要获取最后一条消息状态是否被所有人阅读并将其放入表格单元格中,我必须找到最旧的日期并将其与消息日期进行比较。但要比较日期,我必须将它们从字符串转换为日期。现在假设有 10 个对话,每个对话包含 250 个成员。所以有很多任务,所以我的 cpu 使用率达到 100%。任何更好的解决方案。为了快速,我正在使用以下功能

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
        let dateTransformer = ISODateTransform() // Custom Date Transformer Same as of ios default but with a fixed date format.
        if let lastReadInfoDic = self.conversation?.lastReadDictionary {
            var lastReadData = [String:Date]()
            lastReadInfoDic.forEach({(id,date) in
                if let memberReadDate = dateTransformer.transformFromJSON(date) {
                    lastReadData.updateValue(memberReadDate, forKey: id)
                }
            })
            let sortedData = lastReadData.sorted(by: {$0.value < $1.value})
            if let oldestReader = sortedData.first {
                let oldestReadDate = oldestReader.value
                if itemMessageDate <= oldestReadDate {
                    return .seen
                } else {
                    return .sent
                }
            }
        }
        return .sent
    }

【问题讨论】:

  • 我必须将它们从字符串转换为日期。你不必那样做。 ISO8601 字符串具有可比性。
  • 感谢@vadian 的帮助,因为所有日期字符串都使用z 时区,因此可以比较。

标签: ios objective-c swift swift4


【解决方案1】:

如果我没看错,您需要self.conversation?.lastReadDictionary 中的最短日期。看起来lastReadDictionary[String: String]

如果是这样,则使用compactMapValues(_:)[String: String] 转换为[String: Date]。接下来,使用min(_:) 查找最早的日期。

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
    let dateTransformer = ISODateTransform()

    let oldestReader = conversation?.lastReadDictionary
        .compactMapValues { dateTransformer.transformFromJSON($0) }
        .min { $0.value < $1.value } // NOTE: Comparing Date objects.

    guard let oldestDate = oldestReader?.value else {
        return .sent
    }

    if itemMessageDate <= oldestDate {
        return .seen
    } else {
        return .sent
    }
}

所有时间字符串都使用Z 时区吗?如果是这样,那么您可以使用字符串比较来查找最早的 ISO 时间字符串。获得最早的字符串后,将该 ISO 时间字符串转换为 Date

func getMessageStatus(itemMessageDate: Date) -> BaseMessageStatus {
    let dateTransformer = ISODateTransform()

    let oldestElement = conversation?.lastReadDictionary
        .min { $0.value < $1.value } // NOTE: Comparing String objects.

    guard let string = oldestElement?.value, let oldestDate = dateTransformer.transformFromJSON(string) else {
        return .sent
    }

    if itemMessageDate <= oldestDate {
        return .seen
    } else {
        return .sent
    }
}

【讨论】:

  • 感谢您的帮助。它有效,我将使用字符串比较方法,因为我的所有日​​期字符串都有 z 时区。
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多