属性 'self.myDelegate' 未在 super.init 初始化 - 代表

Property 'self.myDelegate' not initialized at super.init - Delegate

我正在试验协议和委托,但在初始化委托时卡住了。

在我的 class 的顶部,我尝试添加

protocol myDelegateProtocol {
   func clickedCellIndexPath(indexPath: Int)
}

class MyClass {

     var myDelegate : myDelegateProtocol


     override init() {
        super.init()
        self.setup()     // error 1
     }

     required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)  // error 2
     }

}

它开始为两个 init 闭包提供错误

Both errors: Property 'self.myDelegate' not initialized at super.init

我错过了什么或做错了什么?


如果我尝试将其声明为 var myDelegate: myDelegateProtocol?,它不会给出该错误,但它迫使我强制解包 myDelegate! 并且此时它 returns nil。

编辑:如果我强制它在顶部展开,那么我会在以下部分收到错误..

 ...
var myDelegate : myDelegateProtocol!

func handleTap(sender: UITapGestureRecognizer? = nil) {

    if let point = sender?.locationInView(collectionView) {
        print("Y")
        let clickedCell = collectionView!.indexPathForItemAtPoint(point)!.row

        print(clickedCell)  // prints

        self.myDelegate.clickedCellIndexPath(clickedCell) // error here
    }
}

编辑 2:

所以我的完整代码..:[=​​21=]

protocol myDelegateProtocol {
   func clickedCellIndexPath(indexPath: Int)
}

class MyClass {
     var myDelegate: KDRearrangableClickedCellDelegate!

     override init() {
         super.init()
         self.setup()
      }

     required init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
     }

    func setup() {
         if let collectionView = self.collectionView {
             let tap = UITapGestureRecognizer(target: self, action: #selector(KDRearrangeableCollectionViewFlowLayout.handleTap(_:)))
        tap.delegate = self
        collectionView.addGestureRecognizer(tap)
          }
     }

    func handleTap(sender: UITapGestureRecognizer? = nil) {

         if let point = sender?.locationInView(collectionView) {

             let clickedCell = collectionView!.indexPathForItemAtPoint(point)!.row
             print(clickedCell)

             self.myDelegate.clickedCellIndexPath(clickedCell)
         }
    }

此时我收到此错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

您已将 myDelegate 声明为非可选,这意味着它必须在您的 init() 方法中初始化 调用 super.init().如果你的 setup() 方法是你为 myDelegate 赋值的地方(我猜是这种情况,虽然你没有包括你的 setup()'s implementation here), then you need to call setup() before super.init(), and/or declare myDelegate to be Optional (with a '? ').

这是导致问题的行:

var myDelegate : myDelegateProtocol

myDelegate 被声明为非可选的但你没有初始化 它在你的初始化函数中。如果您在 setup() 中初始化它 函数,您需要将 myDelegate 的声明更改为这样。

var myDelegate : myDelegateProtocol!

正如其他人所指出的,因为 myDelegate 未在 init 中初始化,您必须将其设为可选。例如:

var myDelegate: KDRearrangableClickedCellDelegate?

然后当你需要使用它的时候,解开这个可选的,例如:

func handleTap(sender: UITapGestureRecognizer) {
    if let point = sender.locationInView(collectionView) {
        if let clickedCell = collectionView?.indexPathForItemAtPoint(point)?.item {
            print(clickedCell)
            myDelegate?.clickedCellIndexPath(clickedCell)
        }
    }
}

就我个人而言,我建议使用可选的 (KDRearrangableClickedCellDelegate?) 而不是隐式展开的 (KDRearrangableClickedCellDelegate!),这样如果您还没有设置 myDelegate,您的应用不会崩溃。显然,如果要调用 clickedCellIndexPath,则必须实际设置 myDelegate。我也在做 clickedCell 的可选绑定,这样即使点击不在单元格上,它也不会崩溃。另外,我使用 item 而不是 row,因为集合视图通常不使用 item/section 而不是 row/section.

您没有向我们展示您如何设置 collectionView 也没有向我们展示您如何设置 myDelegate,但要使上述工作正常,您需要在正确处理手势之前设置这两项.


顺便说一句,我不知道 MyClass 和它的 myDelegate 之间的关系是什么,但是你经常让委托 weak 来避免强引用循环。为此,将您的协议定义为 class 协议:

protocol myDelegateProtocol : class {
   func clickedCellIndexPath(indexPath: Int)
}

然后定义你的 myDelegateweak:

weak var myDelegate: KDRearrangableClickedCellDelegate?

你只需要这样做,如果对象 MyClassmyDelegate 本身将保持对 MyClass 的强引用。如果不是,你可能不需要让你的代表变弱。这仅取决于您尚未与我们共享的对象模型。