诶之前就在这边问过很基础的问题,现在继续=。=
上到第三课结束的地方了,为了和课程同步,环境还是xcode 6.1.1
然后代码这边的话遵循课程中说到的MVC,编译成功了,编译过程并没有报错,但是在模拟器中打开了这个app之后就跳回来了显示了如下图的问题。
(请忽略我的神经病文风的注释,因为也是跟着视频一点一点打的代码,理解都写在注释里了)
跟着视频敲的代码,实在是找不到什么问题。错误信息也不是很看的明白那个(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()
}
}
是跟着白胡子爷爷的视频学的吧,我初学Swift的时候也看过,也跟着写过这个计算器。
你这段代码的问题@jokester已经说了,就是
let brain = CalculatorBrain()
这句不该放在CalculatorBrain
这个class内部,而且我也知道你并不是想写static let brain = CalculatorBrain()
搞一个单例。这句话应该放在
ViewController
里面。不过说实话老爷爷把
CalculatorBrain
这个类叫做Model也是有点厉害,这样Controller的任务就只是处理用户与View的交互逻辑罢了,具体的计算逻辑都放在这个所谓的Model里。这比大部分人只在Model里放几个属性,然后Controller里一堆代码的做法高明很多。突然有点想重新看一遍视频啊。