【问题标题】:Weak and delegate fail-warnings when trying to update tableview through delegate method尝试通过委托方法更新 tableview 时出现弱和委托失败警告
【发布时间】:2018-07-30 03:20:24
【问题描述】:

我一直在努力通过我制作的另一个课程来更新我的表格视图。 然后我找到了这个stackoverflow解决方案: How to access and refresh a UITableView from another class in Swift

但是当我一步一步执行所有代码时,我得到以下错误:

我的台词:

weak var delegate: UpdateDelegate?

得到警告

'weak' may only be applied to class and class-bound protocol types, not 'UpdateDelegate'

还有我的台词:

self.delegate.didUpdate(self)

收到警告:

Instance member 'delegate' cannot be used on type 'APIgetter'

这可能是因为代码太旧而我使用的是 swift 4 吗?否则我不明白为什么这应该失败。我希望你能帮助我:)

更新:

我的协议:

protocol UpdateDelegate: AnyObject {
    func didUpdate(sender: APIgetter)
}

我的 ViewController 中包含 tableview 的片段:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UpdateDelegate {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        APIgetter.addDataFromSQL()
        let updates = APIgetter()
        updates.delegate = self
    }

    //update func
    func didUpdate(sender: APIgetter) {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }

我在 APIgetter.swift 中的 APIgetter 类:

class APIgetter {
weak var delegate: UpdateDelegate?

class func addDataFromSQL (){

//Code to fetch data from API

//Code that comes after DispatchQueue.global & DispatchQueue.main and my result being executed
//result
self.delegate.didUpdate(self)

【问题讨论】:

    标签: swift delegates


    【解决方案1】:

    只需更新您的协议定义。

    protocol UpdateDelegate: class {
       // protocol body
    }
    

    protocol UpdateDelegate: AnyObject {
       // protocol body
    }
    

    这是必需的(我认为从 Swift 4 开始),因为类是引用类型,您只能对引用类型使用弱引用。不是像结构这样的值类型。

    更新:您无法像当前那样从静态函数访问属性/实例成员。从函数中删除 class 关键字,它应该可以工作。

    如果您希望/需要在整个应用程序中使用此类的单个实例,您可以使用静态属性使其成为单例

    class APIgetter {
        static let shared: APIgetter = APIgetter()
    }
    

    那么你就可以像这样访问它了:

    APIgetter.shared.addDataFromSQL()
    

    您也可以在调用您的函数之前以相同的方式更新委托。

    APIgetter.shared.delegate = self
    

    我认为在这种情况下,我会使用没有委托的单例。只需在您的函数中使用完成处理程序。如果不小心管理,在共享实例上设置和更改委托可能会产生一些副作用。

    【讨论】:

    • 太棒了,谢谢!但我仍然收到“Instance member 'delegate' cannot be used on type 'APIgetter'”错误
    • 您能否发布更多代码,如果不知道您是如何定义类/协议的,这很难提供帮助。什么是 APIgetter?
    • @dafo 对于该错误,请参阅here。基本上,委托是一个 instance 变量。但是,您的 addDataFromSQL 与实例无关,因为您将其定义为 class 函数。如果您从func 中删除class,那么它应该可以工作...
    • 啊是的,就像亲爱的说的那样。您正在访问的函数是静态/类函数,无法访问这样的实例成员。谢谢亲爱的
    猜你喜欢
    • 2018-11-08
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多