我正在为我的学校做一个项目,一个编程主题。我正在 Swift 中使用 Xcode。我想做一个使用陀螺仪的应用程序。我不知道,但不知何故它无法在我的 iphone 上运行,因为我不知道如何修复 Xcode 中的一些错误。当我运行程序时说“致命错误:在解开一个可选值时意外发现 nil
(lldb)"
我的项目的主要内容是使用陀螺仪在 iphone 屏幕上以度数显示旋转(偏航、俯仰、滚动)。如果有人帮助我,我将非常感激。先感谢您。

我的 ViewController 中的代码:

import UIKit
import CoreMotion

class ViewController: UIViewController {

    var currentMaxRotX: Double = 0.0
    var currentMaxRotY: Double = 0.0
    var currentMaxRotZ: Double = 0.0

    let motionManager = CMMotionManager()

    @IBOutlet var rotX : UILabel! = nil
    @IBOutlet var rotY : UILabel! = nil
    @IBOutlet var rotZ : UILabel! = nil

    @IBOutlet var maxRotX : UILabel! = nil
    @IBOutlet var maxRotY : UILabel! = nil
    @IBOutlet var maxRotZ : UILabel! = nil


    @IBOutlet weak var RollLabel: UILabel! = nil

    @IBOutlet weak var PitchLabel: UILabel! = nil

    @IBOutlet weak var YawLabel: UILabel! = nil

    override func viewDidLoad() {

        if motionManager.gyroAvailable {

            if !motionManager.gyroActive {
                motionManager.gyroUpdateInterval = 0.2
                motionManager.startGyroUpdates()
                //motionManager = [[CMMotionManager alloc]init]; should I use this ???
                //motionManager.deviceMotionUpdateInterval = 0.2;
                //motionManager.startDeviceMotionUpdates()

                 motionManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {(gyroData: CMGyroData!, error: NSError!)in
                     self.outputRotationData(gyroData.rotationRate)
                     if (error != nil)
                     {
                         println("\(error)")
                     }
                 })
            }
       } else {
              var alert = UIAlertController(title: "No gyro", message: "Get a Gyro", preferredStyle: UIAlertControllerStyle.Alert)
              alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
              self.presentViewController(alert, animated: true, completion: nil)
    }


     super.viewDidLoad()
    }

    // radians to degrees
    func radians(fromDegrees degrees: Double) -> Double {
        return 180 * degrees / M_PI
    }

    func outputRotationData(rotation:CMRotationRate)
    {
        rotX.text = NSString(format:"Rotation X: %.4f",rotation.x)
        if fabs(rotation.x) > fabs(currentMaxRotX)
        {
            currentMaxRotX = rotation.x
        }

        rotY.text = NSString(format:"Rotation Y: %.4f", rotation.y)
        if fabs(rotation.y) > fabs(currentMaxRotY)
        {
            currentMaxRotY = rotation.y
        }
        rotZ.text = NSString(format:"Rotation Z:%.4f", rotation.z)
        if fabs(rotation.z) > fabs(currentMaxRotZ)
        {
            currentMaxRotZ = rotation.z
        }

        maxRotX.text = NSString(format:"Max rotation X: %.4f", currentMaxRotX)
        maxRotY.text = NSString(format:"Max rotation Y:%.4f", currentMaxRotY)
        maxRotZ.text = NSString(format:"Max rotation Z:%.4f", currentMaxRotZ)

        var attitude = CMAttitude()
        var motion = CMDeviceMotion()
        motion = motionManager.deviceMotion
        attitude = motion.attitude


        YawLabel.text = NSString (format: "Yaw: %.2f", attitude.yaw)    //radians to degress NOT WORKING
        PitchLabel.text = NSString (format: "Pitch: %.2f", attitude.pitch)//radians to degress NOT WORKING
        RollLabel.text = NSString (format: "Roll: %.2f", attitude.roll)//radians to degress NOT WORKING
      }

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

最佳答案

在这两行中,您使用的是隐式解包的选项:您在没有 ?! 的情况下使用它们,但如果它们是 nil ,它们会使您的程序崩溃。在这种情况下,motionManager.deviceMotionnil,因为您在访问之前没有调用 motionManager.startDeviceMotionUpdates()

您的 viewDidLoad 方法是执行此操作的正确位置:

override func viewDidLoad() {

    if motionManager.gyroAvailable {
        motionManager.deviceMotionUpdateInterval = 0.2;
        motionManager.startDeviceMotionUpdates()

        motionManager.gyroUpdateInterval = 0.2
        motionManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue()) {
           [weak self] (gyroData: CMGyroData!, error: NSError!) in

           self?.outputRotationData(gyroData.rotationRate)
           if error != nil {
               println("\(error)")
           }
        }
    } else {
        // alert message
    }

    super.viewDidLoad()
}

还有一些额外的变化:
  • 你不需要在 startGyroUpdates() 之前调用 startGyroUpdatesToQueue()
  • Swift 使用 trailing closures 作为像这样的完成处理程序 - 更好地编写和阅读。
  • 为避免引用循环,在完成处理程序中将 self 声明为 weak - 这需要在访问 self 时使用可选链。
  • 关于ios - 快速陀螺仪偏航、俯仰、滚转,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27783658/

    10-14 23:15