【问题标题】:swift delegate variable is always nilswift 委托变量始终为 nil
【发布时间】:2021-07-05 16:53:20
【问题描述】:

我是一个相对较新的开发人员,并且经常使用协议/委托,但我坚持让这个协议/委托正确实施。我的视图控制器中有一个视图,它为 StarRatingView 分配了一个类。我需要在 viewcontroller 类中捕获 StarRatingView 生成的浮点值。

星级评分工作正常。由于某种原因,我无法设置委托变量。

这里是我定义协议和委托变量的地方。

protocol StarRatingProtocol {
    func receiveStarRating(_ touchedStarRating: Float)
}



@IBDesignable
class StarRatingView: UIView {
    
    var delegate: StarRatingProtocol?  //THIS IS ALWAYS NIL NOT GETTING SET
    

这里是我调用委托函数的地方

    

fileprivate func touched(touch: UITouch, moveTouch: Bool) {
    
        guard !moveTouch || lastTouch == nil || lastTouch!.timeIntervalSince(Date()) < -0.1 else { return }
        print("processing touch")
        guard let hs = self.hstack else { return }
        let touchX = touch.location(in: hs).x
        let ratingFromTouch = 5*touchX/hs.frame.width
        var roundedRatingFromTouch: Float!
        switch starRounding {
        case .roundToHalfStar, .ceilToHalfStar, .floorToHalfStar:
            roundedRatingFromTouch = Float(round(2*ratingFromTouch)/2)
        case .roundToFullStar, .ceilToFullStar, .floorToFullStar:
            roundedRatingFromTouch = Float(round(ratingFromTouch))
        }
        self.rating = roundedRatingFromTouch
        lastTouch = Date()
        
        guard delegate != nil else {return} 
        
        delegate!.receiveStarRating(roundedRatingFromTouch)
}



这是我设置协议并尝试设置委托值的视图控制器类。我应该在 viewdidload 以外的地方设置委托值吗?



class LogController: UIViewController, StarRatingProtocol {
  

    @IBOutlet weak var starRatingView: StarRatingView!
    @IBOutlet weak var labelStarRating: UILabel!
    
    let starRating = StarRatingView()
    var testRating: Float?
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

   
        starRating.delegate = self
    }


【问题讨论】:

    标签: swift delegates protocols


    【解决方案1】:

    问题在于,当您说let starRating = StarRatingView() 时,这是您现在正在创建的新的和不同的 StarRatingView。那不是你想要的;您想要界面中已经存在的 StarRatingView。据推测,如果插座连接正确,那将是self.starRatingView。这就是您需要设置其委托的 StarRatingView。

    另一个(不相关的)问题是delegate 必须是weak。否则会出现retain循环和内存泄漏。

    【讨论】:

    • 成功了!除了弱 var 部分。当我尝试设置弱变量时,我收到错误:'weak' must not be applied to non-class-bound 'StarRatingProtocol';考虑添加具有类绑定的协议一致性。
    • 我刚刚做了一些研究,并认为我发现了 - 将“类”添加到协议中......我会尝试一下。恐怕我对各种类型的变量名称(例如弱和静态等)一无所知。我需要学习所有这些......
    • 在协议中添加 class 是正确的,尽管在现代 Swift 中我们鼓励添加 AnyObject 而不是 class。任何一个都可以。
    • @aheze 是的,他们宣布 Swift 5.2 或 5.3(不记得)他们想要更改它,以使其与协议声明的其他用途以及采用类限制(如protocol P : UIView)
    • @aheze 啊是的,我自己的问题又来困扰我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    相关资源
    最近更新 更多