【问题标题】:Custom protocol is not working in swift自定义协议无法快速运行
【发布时间】:2014-07-30 07:40:27
【问题描述】:

我有两个UIViewControllers HomeViewController 和 ArrangeViewController。

在 ArrangeViewController 中,我有这段代码

import UIKit

protocol ArrangeClassProtocol
{
    func recieveThearray(language : NSMutableArray)
}

class ArrangeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { // class "ArrangeViewController" has no initializer

    var ArrangeClassDelegateObject : ArrangeClassProtocol?

    // Global Variables Goes Here
    var languageNamesArray: NSMutableArray = ["Tamil","English"]
    var userDefaults : NSUserDefaults = NSUserDefaults.standardUserDefaults()
    var tempArray : NSMutableArray = NSMutableArray()

    // Outlets Goes Here
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Saving the Array in a UserDefaultObject
            if userDefaults.boolForKey("languageNamesArrayuserDefaults")
            {
                tempArray = userDefaults.objectForKey("languageNamesArrayuserDefaults") as NSMutableArray
            }
            else
            {
                tempArray = languageNamesArray
            }

        self.tableView.separatorInset = UIEdgeInsetsZero

         // TableView Reordering
        self.tableView.setEditing(true, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func prefersStatusBarHidden() -> Bool
    {
        return true
    }


    // Delegate Methods of the UITableView
     func numberOfSectionsInTableView(tableView: UITableView!) -> Int {

        return 1
    }

     func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {

            return tempArray.count
    }

     func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

        let cell = tableView.dequeueReusableCellWithIdentifier("Arrange", forIndexPath: indexPath) as ArrangeTableViewCell
        cell.languageName.font = UIFont(name: "Proxima Nova", size: 18)
        cell.languageName.text = tempArray.objectAtIndex(indexPath.row) as NSString
        cell.showsReorderControl = true
        return cell
    }

    // Delegate Methods for dragging the cell
     func tableView(tableView: UITableView!, editingStyleForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCellEditingStyle
    {

        return UITableViewCellEditingStyle.None
    }

     func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool
    {
        return true
    }

     func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!)
    {
        var stringToMove = tempArray.objectAtIndex(sourceIndexPath.row) as NSString
        tempArray .removeObjectAtIndex(sourceIndexPath.row)
        tempArray .insertObject(stringToMove, atIndex: destinationIndexPath.row)
    }

     func tableView(tableView: UITableView!, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath!, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath!) -> NSIndexPath!
    {
        let section:AnyObject = tempArray .objectAtIndex(sourceIndexPath.section)
        var sectionCount = tempArray.count as NSInteger
        if sourceIndexPath.section != proposedDestinationIndexPath.section
        {
            var rowinSourceSection:NSInteger =  (sourceIndexPath.section > proposedDestinationIndexPath.section) ? 0 : (sectionCount-1)

            return NSIndexPath(forRow: rowinSourceSection, inSection: sourceIndexPath.row)


        }
        else if proposedDestinationIndexPath.row >= sectionCount
        {

            return NSIndexPath(forRow: (sectionCount-1), inSection: sourceIndexPath.row)
        }


        return proposedDestinationIndexPath
    }

    // Creating the HomeViewController Object and presenting the ViewController
    @IBAction func closeButtonClicked(sender: UIButton)
    {
        userDefaults.setObject(tempArray, forKey: "languageNamesArrayuserDefaults")
        userDefaults.synchronize()
        ArrangeClassDelegateObject?.recieveThearray(languageNamesArray)
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

在 HomeViewController 中,我写了这段代码。

class HomeViewController: UIViewController, ArrangeClassProtocol {

   var ArrangeClassObject : ArrangeViewController = ArrangeViewController() // ArrangeViewController is Constructible with ()
  override func viewDidLoad() {
        super.viewDidLoad()

        self.ArrangeClassObject.ArrangeClassDelegateObject = self
}

func recieveThearray(language: NSMutableArray)
    {
        println(language)
    }
}

我想访问从 ArrangeViewController 传递的数组。但它显示的错误是我在声明附近注释掉的。我还将可选值与 HomeViewController 一起使用,它还显示错误并使应用程序崩溃。请有人帮忙解决这个问题。

我从 github 帖子中得到了这个想法。在那个项目中,他使用了一个 UIViewController 和另一个 swift 类。这对我来说也是可能的。但我想用这两个UIViewControllers 解决它。

【问题讨论】:

  • 我无法重现您的“类“ArrangeViewController”没有初始化程序”错误。你在最新的测试版,测试版 4 上吗?你还有其他房产吗?当您单击错误时,您是否获得有关哪个属性导致错误的更多信息(如果我通过添加未初始化的属性来强制您的错误,我会收到“修复它”的提示,告诉我哪个属性是问题。)您能否发布一个完整的简短示例来重现您的错误?
  • (另外,您的第二个错误只是您的第一个错误的副作用,假设您的错误消息实际上是“ArrangeViewController is not Constructible with ()”......那是因为Swift 找不到有效的初始化程序,因为您的 ArrangeViewController 已被导致第一个错误的任何原因破坏。)
  • @MattGibson 没有其他选项可以查看错误。 xcode 仅显示这两个错误。我不知道该怎么做。我可以初始化一些东西吗??
  • @MattGibson 我正在使用 xcode6-beta4
  • @MattGibson 请标记这个问题吗?让大家看到。。我很想解决这个问题。

标签: ios uiviewcontroller swift protocols


【解决方案1】:

感谢您提供新代码。创建错误消息的问题在这里:

@IBOutlet weak var tableView: UITableView!

如果您将此代码更改为:

@IBOutlet weak var tableView: UITableView?

然后编译器将停止抱怨缺少初始化程序。

但是,这更像是一种诊断工具,而不是问题的实际解决方法,即您需要一个初始化程序。我认为正在发生的事情是,直到您在层次结构中自己的类级别添加未初始化的属性,您才会获得默认初始化程序。在您添加未初始化属性时,Swift 将停止生成默认初始化程序,并希望您提供自己的初始化程序。

如果您检查 UIViewController 的标题,您会发现以下建议:

/*
  The designated initializer. If you subclass UIViewController, you must call the super implementation of this
  method, even if you aren't using a NIB.  (As a convenience, the default init method will do this for you,
  and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should
  have its class set to your view controller subclass, with the view outlet connected to the main view. If you
  invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose
  name is the same as your view controller's class. If no such NIB in fact exists then you must either call
  -setView: before -view is invoked, or override the -loadView method to set up your views programatically.
*/
init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)

所以,也许只是尝试:

init()  {
    super.init(nibName: nil, bundle: nil)
}

...应该恢复最初提供的初始化程序的功能。我猜您的 IBOutlet 将通过基类的初始化程序从 Storyboard 中正确“预热”,并且您应该再次能够使用无参数初始化程序构造视图控制器。

【讨论】:

  • 我已经更新了我的答案。不过,就我对视图控制器的初始化如何工作的了解而言,我可能有点手足无措。我会等到其他几个人有机会检查这个问题并获得更多意见。现在你已经发布了足够的代码来重现这个问题,我已经支持你的问题。
猜你喜欢
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
相关资源
最近更新 更多