簡體   English   中英

如何從數組中刪除對象,其中對象符合協議?

[英]How to remove an object from an array, where the object conforms to a protocol?

我正在跟蹤數組delegates中的許多委托對象

要成為有效的委托,對象需要符合BSBSystemDelegate協議。

所以這里是數組聲明:

private var delegates: [BSBSystemDelegate] = []

當一個對象向 BSBSystem 注冊時,它會被附加到數組中:

public func registerDelegateWith(_ viewController: BSBSystemDelegate)
{
    self.delegates.append(viewController)
}

這工作正常。

我在 swift 中遇到的問題是,當我需要“注銷”一個委托時,它的語法很糟糕且令人困惑,即將它從數組中刪除,如果它存在的話。

這是我嘗試過的:


public function deregisterDelegate(_ viewController: BSBSystemDelegate)
{
    for delegate in self.delegates
    {
        if delegate === viewController
        {
            self.delegates.removeAll(where: viewController)
        }
    }
}

那行不通。

當它與我要求刪除的對象相同時,我只想刪除數組中的對象。

我已經快速戰斗了一個多小時。 有人可以解釋我哪里出錯了嗎?

這是蘋果的例子:

在此處輸入圖片說明

這是我的代碼和它不斷給我的瘋狂愚蠢的錯誤:

在此處輸入圖片說明

self.delegates.removeAll(where: { $0 === viewController })可以使用,但您的協議需要聲明為類綁定,以便使用僅適用於引用類型的===運算符。

您必須將您的協議聲明為:

protocol BSBSystemDelegate: AnyObject {
    ...
}

錯誤消息沒有用,因為編譯器很困惑,但是如果您將閉包聲明放在單獨的行上:

let shouldBeRemoved: (BSBSystemDelegate) -> Bool = { $0 === viewController }
self.delegates.removeAll(where: shouldBeRemoved)

你得到一個更有用的binary operator '===' cannot be applied to two 'BSBSystemDelegate' operands消息。

假設您更改了協議以使其成為類綁定,如 Dan 所述,您還可以使用如下代碼:

if let index = array.firstIndex(where: { $0 === aFoo }) {
    array.remove(at: index)
}

對於大型數組,這可能會更快,因為它會在第一次匹配時停止。 removeAll(where:)將始終檢查數組中的每個元素是否匹配。)

但是,如果多次添加完全相同的對象,上面的代碼只會從數組中刪除對象的第一個實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM