【问题标题】:Array of UIButtons, got error: "Unexpectedly found nil while unwrapping optional value"UIButtons 数组,出现错误:“在展开可选值时意外发现 nil”
【发布时间】:2014-10-07 00:25:57
【问题描述】:

我尝试在子类中调用startGame() 方法,但是,nButton 似乎没有初始化。

错误是

在展开可选值时意外发现 nil。


代码:

import UIKit

class ViewController: UIViewController {

    @IBOutlet var startButton: UIButton?
    @IBOutlet var nButton: Array<UIButton>?
    @IBOutlet var overLable: UILabel?

    func indexOf(buttonToFind:UIButton,array:Array<UIButton>)->Int
    {
        var count = 0
        for item in array
        {
            if(buttonToFind != item)
            {
                count++
            }
            else
            {
                break
            }
        }
        return count
    }

    var deck = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25",]
    var next = 0

    @IBAction func pressButton(sender: UIButton)
    {
        var buttonIndex  = indexOf(sender, array: nButton!)
        if(sender.titleLabel.text != deck[next])
        {
            overLable!.text = "Game Over"
            time.invalidate()
            presentViewController((self.storyboard.instantiateViewControllerWithIdentifier("container")) as UIViewController, animated: true, completion: nil)

        }
        else
        {
            overLable!.text = "Go on"
            next++
        }
        for(var i=0; i<25; i++)
        {
            nButton![i].enabled=((next<25))
        }

        if(next==25)
        {
            overLable!.text = "Congratulations"
            presentViewController((self.storyboard.instantiateViewControllerWithIdentifier("container")) as UIViewController, animated: true, completion: nil)
        }
    }

    var count = 20
    var time = NSTimer()

    @IBAction func start(sender: UIButton)
    {
        startGame()
        startButton!.enabled = (startButton!.titleLabel.text == "Start")
    }

    func update()
    {
        startButton!.setTitle("\(count--)", forState: UIControlState())
        //timeLable2.text = "\((count--)%10)"
        if(count < 0)
        {
            time.invalidate()
            overLable!.text = "Game Over"
        }
    }

    func startGame()
    {
        var number = [UInt32]()

        func displayNumber(index:Int) -> UInt32
        {
            for( var i = 0; i<100; i++)
            {
                var num = 0
                var inta = arc4random()%25+1
                for item in number
                {
                    if(inta == item)
                    {
                        num++
                    }
                }
                if(num==0)
                {
                    number.append(inta)
                }
            }
            return number[index]
        }

        for (var i = 0; i<25; i++ )
        {
            //HERE IS THE ERROR...
            nButton![i].setTitle("\(displayNumber(i))", forState: UIControlState())
        }

        overLable!.text=""
        next = 0

        for(var i=0; i<25; i++)
        {
            nButton![i].enabled=(next==0)
        }

        time.invalidate()
        count = 30

        time = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: ("update"), userInfo: nil, repeats: true)
    }
}

ContainerVC 类:

import UIKit

class ContainerViewController: ViewController
{
    @IBAction func restartButton(sender: UIButton)
    {
        dismissViewControllerAnimated(true, completion: nil)
        super.startGame()
    }
}

有人知道怎么处理吗?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    据我了解:nButton[i] 必须是匹配 .xib 文件中 UIButton 的引用出口。因为您在界面构建器中为棋盘游戏创建了按钮。

    您是否在调试器和po nButton[i] 处停了下来(并确保还检查 nButton 数组也不是 nil)?

    我看不到您正在为 nButton 分配一个数组。喜欢self.nButton = Array&lt;UIButton&gt;()

    如果您在其他任何地方分配了数组,我也看不到您将所有按钮都添加到 nButton 数组中。


    nButton 作为按钮数组的名称令人困惑 ;-)。


    indexOf 方法可能不需要,因为您可以简单地将每个按钮添加一个tag(一个数字)。可以在界面生成器中轻松设置。也许你甚至不再需要数组了。

    然后你可以像这样使用标签检查索引:

    switch sender.tag {
        case 1:
            //index of button is one, do something
        default:
            //index of button is not relevant do nothing
    }
    

    【讨论】:

    • nButton 是一个 IBOutlet 集合,它是通过控制将故事板上的所有 25 个按钮拖动到 VC 来创建的。问题是,如果我没有在子类中添加“super.startGame()”,应用程序运行完美。现在我希望应用程序在游戏赢或输时弹出另一个 VC。那么在弹出新的 VC 后,数组可能设置为 nil 吗?我只想在子类中按下重启按钮后重新执行超类中的代码。
    • @Gellert 但是你如何添加新的视图和视图控制器。有很多方法,有些是释放旧视图,有些不是(一种方法是modal)。我改变了我的答案,如果你使用tag,可能你不需要代码中的数组
    • presentViewController((self.storyboard.instantiateViewControllerWithIdentifier("container")) 作为 UIViewController,动画:true,完成:nil)
    • 谢谢,我会试试标签:D
    • 是的,你用新的 ViewController 替换旧的 ViewController 来破坏它。您想要推送新的 ViewController 或只是添加另一个 viewController (viewController.addSubview(newViewcontroller.view)) 的视图。每次使用该方法时,都会创建、显示一个新的 ViewController 实例,并释放旧的实例,并释放所有附加到它的属性,如集合和按钮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多