Вы можете использовать static var
, чтобы установить поле, которое вы хотите использовать для сравнения:
class NotificationInformation: Equatable {
enum CompareField {
case type, mediaUID, commentUID, likeUID
}
static var compareField: CompareField = .mediaUID
let type: String
let mediaUID: String?
let commentUID: String?
let likeUID:String?
init(type: String, mediaUID: String? = nil, commentUID: String? = nil, likeUID: String? = nil) {
self.type = type
self.mediaUID = mediaUID
self.commentUID = commentUID
self.likeUID = likeUID
}
static func ==(lhs: NotificationInformation, rhs: NotificationInformation) -> Bool {
switch NotificationInformation.compareField {
case .type:
return lhs.type == rhs.type
case .mediaUID:
return lhs.mediaUID == rhs.mediaUID
case .commentUID:
return lhs.commentUID == rhs.commentUID
case .likeUID:
return lhs.likeUID == rhs.likeUID
}
}
}
Пример:
let a = NotificationInformation(type: "foo", mediaUID: "123")
let b = NotificationInformation(type: "bar", mediaUID: "123")
NotificationInformation.compareField = .type
if a == b {
print("same type")
}
NotificationInformation.compareField = .mediaUID
if a == b {
print("same mediaUID")
}
Выход:
same mediaUID
Сравнение нескольких полей с использованием OptionSet
Если вы замените enum
на OptionSet
, вы можете выбрать несколько полей для сравнения:
struct CompareFields: OptionSet {
let rawValue: Int
static let type = CompareFields(rawValue: 1 << 0)
static let mediaUID = CompareFields(rawValue: 1 << 1)
static let commentUID = CompareFields(rawValue: 1 << 2)
static let likeUID = CompareFields(rawValue: 1 << 3)
}
static var compareFields: CompareFields = .mediaUID
static func ==(lhs: NotificationInformation, rhs: NotificationInformation) -> Bool {
var equal = true
if NotificationInformation.compareFields.contains(.type) {
equal = equal && (lhs.type == rhs.type)
}
if NotificationInformation.compareFields.contains(.mediaUID) {
equal = equal && (lhs.mediaUID == rhs.mediaUID)
}
if NotificationInformation.compareFields.contains(.commentUID) {
equal = equal && (lhs.commentUID == rhs.commentUID)
}
if NotificationInformation.compareFields.contains(.likeUID) {
equal = equal && (lhs.likeUID == rhs.likeUID)
}
return equal
}
Пример * +1029 *
let a = NotificationInformation(type: "foo", mediaUID: "123", commentUID: "111")
let b = NotificationInformation(type: "bar", mediaUID: "123", commentUID: "111")
NotificationInformation.compareFields = .mediaUID
if a == b {
print("same mediaUID")
}
NotificationInformation.compareFields = [.mediaUID, .commentUID]
if a == b {
print("same mediaUID and commentUID")
}
выход
same mediaUID
same mediaUID and commentUID
Многопоточный выпуск
Существует проблема, если ваш код изменяет значение compareFields
в другом потоке. Значение равно будет меняться для всех потоков. Одним из возможных решений является изменение и использование равенства для NotificationInformation
в главном потоке.
...
} else if notification.type == "media" {
DispatchQueue.main.async {
NotificationInformation.compareFields = .mediaUID
guard let index = strongSelf.notificationsArray.index(of: notification) else {return}
// use index
...
}
}
...