无法从另一个类访问变量?

时间:2014-12-08 00:11:29

标签: ios class variables swift reduce

所以我有一个名为FoodListTable的类UITableViewController 我还有一个变量,可以找到数组中元素的总和:

var calorieTotal: Float {
    return calorieNumberArray.reduce(0 as Float) { $0 + Float($1) }
}

我做了一些测试,这个变量正确计算。但是,当我尝试在名为Menu的另一个类中使用它时,它计算为0.0。我试过这样做:

@IBAction func calculateButtonTappedMenu(sender: AnyObject) {
let foodListTableAccess = FoodListTable()
let dividend = foodListTableAccess.calorieTotal

但是当我这样做时,var calorieTotal仍然计算为0.0。我怎样才能解决这个问题?我是编程新手,所以请提供我需要修复的所有代码。此外,如果需要,这两个类中的所有代码都是:

class FoodListTable: UITableViewController {
var calorieNumberArray = [0,0,0,0,0,0,0,0,0]
var foods = [Food]()
override func viewDidLoad() {
    super.viewDidLoad()
    self.foods = [Food(Name: "Small French Fries: 197 Cal."),Food(Name: "Cheeseburger: 359 Cal., One Patty"),Food(Name: "Cheese Pizza: 351 Cal., One Slice"),Food(Name: "Fried Chicken Breast: 320 Cal."),Food(Name: "Large Taco: 571 Cal."),Food(Name: "Hotdog: 315 Cal., With Ketchup"),Food(Name: "Tuna Sandwich: 287 Cal."),Food(Name: "1 Cup Vanilla Ice Cream: 290 Cal."),Food(Name: "1 1/2 Cup Vegetable Salad: 30 Cal.")]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.foods.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    var food : Food
    food = foods[indexPath.row]
    cell.textLabel.text = food.Name
    tableView.deselectRowAtIndexPath(indexPath, animated: true)

    return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        if cell.accessoryType == .None {

            if indexPath.row == 0 {
                calorieNumberArray[0] = 197
            }
            if indexPath.row == 1 {
                calorieNumberArray[1] = 359
            }
            if indexPath.row == 2 {
                calorieNumberArray[2] = 351
            }
            if indexPath.row == 3 {
                calorieNumberArray[3] = 320
            }
            if indexPath.row == 4 {
                calorieNumberArray[4] = 571
            }
            if indexPath.row == 5 {
                calorieNumberArray[5] = 315
            }
            if indexPath.row == 6 {
                calorieNumberArray[6] = 287
            }
            if indexPath.row == 7 {
                calorieNumberArray[7] = 290
            }
            if indexPath.row == 8 {
                calorieNumberArray[8] = 30
            }
            cell.accessoryType = .Checkmark
        } else {

            if indexPath.row == 0 {
                calorieNumberArray[0] = 0
            }
            if indexPath.row == 1 {
                calorieNumberArray[1] = 0
            }
            if indexPath.row == 2 {
                calorieNumberArray[2] = 0
            }
            if indexPath.row == 3 {
                calorieNumberArray[3] = 0
            }
            if indexPath.row == 4 {
                calorieNumberArray[4] = 0
            }
            if indexPath.row == 5 {
                calorieNumberArray[5] = 0
            }
            if indexPath.row == 6 {
                calorieNumberArray[6] = 0
            }
            if indexPath.row == 7 {
                calorieNumberArray[7] = 0
            }
            if indexPath.row == 8 {
                calorieNumberArray[8] = 0
            }
            cell.accessoryType = .None
        }
    }
    println(calorieNumberArray)
    println(calorieTotal)
}
var calorieTotal: Float {
    return calorieNumberArray.reduce(0 as Float) { $0 + Float($1) }
}
}
class Menu: Calculator {

@IBOutlet weak var yourWeightTextFieldMenu: UITextField!
@IBOutlet weak var exerciseListPickerViewMenu: UIPickerView!
@IBOutlet weak var calculateButtonMenu: UIButton!
@IBOutlet weak var calculatorContainerMenu: UIView!
@IBOutlet weak var answer1LabelMenu: UILabel!

override func viewDidLoad() {
    calculatorContainerMenu.hidden = false
    answer1LabelMenu.hidden = true
    yourWeightTextFieldMenu.delegate = self
    exerciseListPickerViewMenu.delegate = self
    exerciseListPickerViewMenu.dataSource = self
    calculateButtonMenu.enabled = false
    yourWeightTextFieldMenu.addTarget(self, action:"yourWeightEditingChanged:", forControlEvents:.EditingChanged);
}
override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
    if textField == yourWeightTextFieldMenu {
        yourWeightFilled = text.toInt() != nil
    }
    return true
}
override func textFieldShouldClear(textField: UITextField) -> Bool {
    calculateButtonMenu.enabled = false
    return true
}
@IBAction func yourWeightEditingDidEndMenu(sender: AnyObject) {
    yourWeightTextFieldMenu.resignFirstResponder()
    self.yourWeight = (self.yourWeightTextFieldMenu.text as NSString).floatValue
}
override func validateCalculateButton() {
    self.calculateButtonMenu.enabled = (self.yourWeightFilled)
}
@IBAction func yourWeightEditingChangedMenu(sender: AnyObject) {
    self.validateCalculateButton()
}
@IBAction func calculateButtonTappedMenu(sender: AnyObject) {
    calculatorContainerMenu.hidden = true
    answer1LabelMenu.hidden = false
    let foodListTableAccess = FoodListTable()
    let divisor = (yourWeight * exerciseCurrentValue)
    let dividend = foodListTableAccess.calorieTotal
    let result = (round(dividend / divisor))
    answer1LabelMenu.text = "It will take you about \(result) minutes to burn off those menu choices by performing that exercise."
    println("divisor: \(divisor), dividend: \(dividend), result: \(result)")
}
}

谢谢!

2 个答案:

答案 0 :(得分:2)

问题是您正在创建类的新实例而不是获取当前实例。如果您实际上使用的是UINavigationController,并且正如您在评论中所说的那样立即从Menu转换为FoodListTable,则类似以下代码的内容应允许您访问该实例当前在导航堆栈上的FoodListTable

@IBAction func calculateButtonTappedMenu(sender: AnyObject) {

    let navigationController: UINavigationController = self.navigationController!
    let numberOfViewControllers = navigationController.viewControllers.count
    var foodListTableAccess: FoodListTable = navigationController.viewControllers[numberOfViewControllers - 2] as FoodListTable

    let dividend = foodListTableAccess.calorieTotal

}

编辑:如果您的代码实际上没有按照您的想法构建UINavigationController,但实际上您正在使用另一条评论中提到的故事板,这里是您可以执行的传递视图控制器对象的方法来自上一课。

FoodListTable视图控制器中,更新prepareToSegue以共享您当前的FoodListTable实例:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    // (Uncomment the if block and specify a segue if this isn't the
    // segue leading from your view controller.)
    //if segue.identifier == "yourSegueName" {
    let menu = segue.destinationViewController as Calculator
    menu.foodListTable = self;
    //}
}

然后在Menu视图控制器中添加一个对应的类变量来保存FoodListTable对象:

class TableViewController: UITableViewController {

    var foodListTable: FoodListTable!

这样你就可以在Menu中访问它的值,如下所示:

@IBAction func calculateButtonTappedMenu(sender: AnyObject) {
    let dividend = foodListTable.calorieTotal
}

答案 1 :(得分:-1)

我知道你说你不熟悉编程。我认为你写的程序对于你的第一次尝试来说有点太复杂了。在处理这项任务之前,你应该花更多的时间在游乐场玩耍。

现在回到眼前的问题......想一想calorieNumberArray,用什么方法填充必要的数据?如何创建FoodListTable的新实例会导致该数组被填充?它不是。

您需要做的是将信息传递到Menu对象,而不是试图将其从FoodListTable中删除。如何执行此操作取决于Menu对象的创建方式以及FoodListTableMenu之间的关系。

我建议您删除在问题中发布的代码,然后输入足够的代码,向我们展示如何创建Menu对象以及如何控制它。然后,我们可以向您展示将数据从FoodListTable传递到Menu的最佳方式。

如果你手动将Menu推到堆栈的某个地方,那么在创建之后立即将卡路里信息传递给它。如果您正在使用故事板和segues,请将信息传递到Menu方法中的prepareForSegue