swift基础问题,求指教

诶之前就在这边问过很基础的问题,现在继续=。=
上到第三课结束的地方了,为了和课程同步,环境还是xcode 6.1.1

然后代码这边的话遵循课程中说到的MVC,编译成功了,编译过程并没有报错,但是在模拟器中打开了这个app之后就跳回来了显示了如下图的问题。
(请忽略我的神经病文风的注释,因为也是跟着视频一点一点打的代码,理解都写在注释里了)

clipboard.png

跟着视频敲的代码,实在是找不到什么问题。错误信息也不是很看的明白那个(lldb)
整块代码是这样的:
谢谢了!T T

import Foundation
//不要任何关于UI的内容,因为这里是model

class CalculatorBrain
{
    //首先创建一个类型为op的数组,这个数组会在下面的enum op中定义,然后将其实例化为opstack
    private var opStack = [Op]()
    
    //枚举三种情况,这三种情况
    private enum Op
    {
        case Operand(Double)//一个数
        case UnaryOpertaion(String, Double -> Double)//一个运算符和一个数的运算(运算为一个函数,参数是double,类型也是double)
        case BinaryOpertaion(String, (Double,Double) -> Double)//一个运算符和两个数的运算(运算为一个函数,参数是两个double,类型是double)
    }
    
    //创建一个字典,对应数值和运算方法。
    private var knownOps = [String:Op]()
    
    /*初始化时,先给好knownOps的值,分别为,
    x:BinaryOpertaion,
    ÷:BinaryOpertaion,
    +:BinaryOpertaion,
    -:BinaryOpertaion,
    √:UnaryOpertaion*/
    init()
    {
        knownOps["×"] = Op.BinaryOpertaion("×", *)
        knownOps["÷"] = Op.BinaryOpertaion("÷"){ $1 / $0 }
        knownOps["+"] = Op.BinaryOpertaion("+", +)
        knownOps["-"] = Op.BinaryOpertaion("-"){ $1 - $0 }
        knownOps["√"] = Op.UnaryOpertaion("√"){ sqrt($0) }
    }
    
    let brain = CalculatorBrain()
    
    func pushOperand(operand: Double ) -> Double? //输入一个数,没有运算
    {
        opStack.append(Op.Operand(operand))//如果这仅仅是一个数,那就作为Op.Operand类型传入
        println(Op.Operand(operand))//类似于opstack[x]的这种感觉
        return evaluate()
    }
    
    func evaluate() -> Double?{//为什么double要用optional?其实这个还不是很明白。
        //这是evalaute的起始位置,上面的evaluate都是从这里开始的。
        let(result, remainder) = evaluate(opStack)
        return result
    }
    
    private func evaluate(ops: [Op]) -> (result: Double?, remainingOps: [Op])//输出的东西叫做tuple,算是一个好几个数据的小组合吧,类似于dictionary
    {
        if !ops.isEmpty{//如果ops不是空的
            var remainingOps = ops //因为ops是作为参数传入的,传入之后默认的就是一个只读的变量,所以要再赋值给一个可变的变量
            let op = remainingOps.removeLast()//这样就可以读取最后的那个元素了。那个原始还是一个op类型的东东。
            switch op
            {//下面我们来看看这这个元素是什么
            case .Operand(let operand)://如果是一个数字,这个operand就是同时传过来的那个数,相当于enum中的Op.Operand(let operand)
                return (operand, remainingOps)//输出一个数字和剩下的栈
            case .UnaryOpertaion(_, let operation)://如果是一个一元操作符,情况会稍微复杂一些
                let operandEvaluation = evaluate(remainingOps)//看来我们需要对operandEvaluation
                if let operand = operandEvaluation.result{//那我们就去看下
                    return (operation(operand), operandEvaluation.remainingOps)
                }
            case .BinaryOpertaion(_, let operation):
                let op1Evaluation = evaluate(remainingOps)
                if let operand1 = op1Evaluation.result{
                    let op2Evaluation = evaluate(op1Evaluation.remainingOps)
                    if let operand2 = op2Evaluation.result{
                        return (operation(operand1,operand2),op2Evaluation.remainingOps)
                    }
                }
            }
        }
        return (nil, ops)//如果栈中什么都不剩了,那就返回一个nil,所以返回值
        
    }

    func performOperaction(symbol: String) ->Double?
    {
        if let operation = knownOps[symbol]//operation是一个optional op的类型,所以,这个赋值可以作为一个条件判断。当值为nil的时候,那if就是false,否则if的条件为true
        {
            opStack.append(operation)
        }
        return evaluate()
    }
}
阅读 3.5k
3 个回答

是跟着白胡子爷爷的视频学的吧,我初学Swift的时候也看过,也跟着写过这个计算器。

你这段代码的问题@jokester已经说了,就是let brain = CalculatorBrain()这句不该放在CalculatorBrain这个class内部,而且我也知道你并不是想写static let brain = CalculatorBrain()搞一个单例。

这句话应该放在ViewController里面。

不过说实话老爷爷把CalculatorBrain这个类叫做Model也是有点厉害,这样Controller的任务就只是处理用户与View的交互逻辑罢了,具体的计算逻辑都放在这个所谓的Model里。这比大部分人只在Model里放几个属性,然后Controller里一堆代码的做法高明很多。突然有点想重新看一遍视频啊。

class CalculatorBrain { 
    let brain = CalculatorBrain()
}

这是在..递归地创建对象?

去掉这句后我在playground里可以成功造出CalculatorBrain对象

我怀疑你是想写

class CalculatorBrain {
    static let brain = CalculatorBrain()
}

Brain的实例是创建在ViewController中的,而不是在其自身内部

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题