如何从数组中删除特定对象?
How to remove specific object from array?
如果调用者传入一个MyDelegate类型的对象,并且在数组中,我想将其从数组中移除。
protocol MyDelegate {
}
private var delegates = [MyDelegate]()
...
...
func removeDelegate(_ delegate: MyDelegate) {
if let index = self.delegates.index(where: { [=10=] == delegate }) {
log.trace("Removing delegate \(delegate)");
self.delegates.remove(at: index)
}
}
有没有更简单的方法来做到这一点?
这个条件“{ $0 == delegate }”导致错误 "Cannot convert value of type '(OptionalNilComparisonType) -> Bool' to expected argument type '() -> Bool'"。我怎样才能解决这个问题?我试过添加 ?和 !但仍然没有完全理解Swift的可选概念。
我正在使用 Xcode 8.2.1 和 Swift 3(?)。
- Is there a less complicated way to do this?
您可以在访问delegates
成员时省略self
,并将index(where:)
调用的结果索引烘焙到对Optional
的 map
方法:
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { [=10=] == delegate})
.map { delegates.remove(at: [=10=]) }
}
如果没有找到这样的 delegate
对象,上面的表达式只是结果 nil
(非捕获结果)。
This conditional, "{ [=23=] == delegate }
", is giving causing the error,
"Cannot convert value of type '(OptionalNilComparisonType) -> Bool
' to
expected argument type '() -> Bool
'". How can I fix this? I've tried
adding ?
and !
but still not fully understanding Swift's optional
concept.
这是 Swift 中另一种模糊错误消息的示例。核心错误是 MyDelegate
没有定义 ==
运算符(不符合 Equatable
)。
然而,在你的编辑之后,你显示 MyDelegate
是一个协议,所以如果你让它符合 Equatable
,你将无法(因为它将包含一个 Self
类型要求)使用 MyDelegate
作为具体类型(仅作为泛型上的类型约束)。
如果您的具体委托对象是引用对象 (class
),并且您想在测试两者是否引用同一对象(对象引用)的意义上测试对象相等性,您可以使用class 实例可用的 ObjectIdentifier
。将 MyDelegate
(在你编辑后你显示它是一个协议)限制为仅 classes,
protocol MyDelegate: class { /* ... */ }
并在上面的 index(where:)
调用中测试 ObjectIdentifier
的相等性:
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { ObjectIdentifier([=12=]) == ObjectIdentifier(delegate) })
.map { delegates.remove(at: [=12=]) }
}
查看 ObjectIdentifier
的源代码,我们发现这将比较两个 delegate
实例的底层原始 ptr 值;来自 swift/stdlib/public/core/ObjectIdentifier.swift:
public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool {
return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value))
}
正如@MartinR 在对上述问题的评论中提到的,除了通过 ObjectIdentifier
,您还可以直接对 class 实例使用 ===
身份运算符。
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { [=14=] === delegate })
.map { delegates.remove(at: [=14=]) }
}
为了完整性,我们可以通过查看 [=] 来验证 ===
使用与 ObjectIdentifier
的 ==
运算符相同的 Builtin
方法54=]:
public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool {
switch (lhs, rhs) {
case let (l?, r?):
return Bool(Builtin.cmp_eq_RawPointer(
Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(l)),
Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(r))
))
case (nil, nil):
return true
default:
return false
}
}
如果调用者传入一个MyDelegate类型的对象,并且在数组中,我想将其从数组中移除。
protocol MyDelegate {
}
private var delegates = [MyDelegate]()
...
...
func removeDelegate(_ delegate: MyDelegate) {
if let index = self.delegates.index(where: { [=10=] == delegate }) {
log.trace("Removing delegate \(delegate)");
self.delegates.remove(at: index)
}
}
有没有更简单的方法来做到这一点?
这个条件“{ $0 == delegate }”导致错误 "Cannot convert value of type '(OptionalNilComparisonType) -> Bool' to expected argument type '() -> Bool'"。我怎样才能解决这个问题?我试过添加 ?和 !但仍然没有完全理解Swift的可选概念。
我正在使用 Xcode 8.2.1 和 Swift 3(?)。
- Is there a less complicated way to do this?
您可以在访问delegates
成员时省略self
,并将index(where:)
调用的结果索引烘焙到对Optional
的 map
方法:
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { [=10=] == delegate})
.map { delegates.remove(at: [=10=]) }
}
如果没有找到这样的 delegate
对象,上面的表达式只是结果 nil
(非捕获结果)。
This conditional, "
{ [=23=] == delegate }
", is giving causing the error, "Cannot convert value of type '(OptionalNilComparisonType) -> Bool
' to expected argument type '() -> Bool
'". How can I fix this? I've tried adding?
and!
but still not fully understanding Swift's optional concept.
这是 Swift 中另一种模糊错误消息的示例。核心错误是 MyDelegate
没有定义 ==
运算符(不符合 Equatable
)。
然而,在你的编辑之后,你显示 MyDelegate
是一个协议,所以如果你让它符合 Equatable
,你将无法(因为它将包含一个 Self
类型要求)使用 MyDelegate
作为具体类型(仅作为泛型上的类型约束)。
如果您的具体委托对象是引用对象 (class
),并且您想在测试两者是否引用同一对象(对象引用)的意义上测试对象相等性,您可以使用class 实例可用的 ObjectIdentifier
。将 MyDelegate
(在你编辑后你显示它是一个协议)限制为仅 classes,
protocol MyDelegate: class { /* ... */ }
并在上面的 index(where:)
调用中测试 ObjectIdentifier
的相等性:
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { ObjectIdentifier([=12=]) == ObjectIdentifier(delegate) })
.map { delegates.remove(at: [=12=]) }
}
查看 ObjectIdentifier
的源代码,我们发现这将比较两个 delegate
实例的底层原始 ptr 值;来自 swift/stdlib/public/core/ObjectIdentifier.swift:
public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value)) }
正如@MartinR 在对上述问题的评论中提到的,除了通过 ObjectIdentifier
,您还可以直接对 class 实例使用 ===
身份运算符。
func removeDelegate(_ delegate: MyDelegate) {
delegates.index(where: { [=14=] === delegate })
.map { delegates.remove(at: [=14=]) }
}
为了完整性,我们可以通过查看 [=] 来验证 ===
使用与 ObjectIdentifier
的 ==
运算符相同的 Builtin
方法54=]:
public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool { switch (lhs, rhs) { case let (l?, r?): return Bool(Builtin.cmp_eq_RawPointer( Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(l)), Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(r)) )) case (nil, nil): return true default: return false } }