CMMotionManager is a global resource? What does th

2019-07-29 10:55发布

问题:

I am trying to initialize the CMMotionManager so start updates and create a reference attitude matrix, and then when i click a button trough the storyboard, i display a different screen (which is in a viewcontroller) and i want to use the reference attitude matrix and other readings from the motion manager but if I do a simple check to see if its ready it says it isnt (even thought it was ready on the previous screen).

So I was researching a little bit and i came across some standford notes that say it is a global resource so that it is ok to either use delegates or classes, that got me thinking.

If i use a delegate then technically the owner of the resource is doing the action for me right? so it doesnt really mean it is global.

What about classes? i tried implementing a MotionManager Class but i still didnt get any readings on the second screen... and i just didnt initialize it again on the new screen because i dont want to have multiple instances runing at the same time.

To solve my problem i also suppose i could initialize it once in the main one, save the attitude, pass it to the next one in a segue transition and just re initialize the motion manager so i only have 1 instance (or close old one on screen will dissapear).

But i do not want this because the user might click right away on the screen and the motion manager does take a little bit of time to initialize (or thats what i noticed).

Thanks in advance for any help you can provide.

EDIT:

Ok i tried the delegate method and i still cant read from the device manager in the second window. What comes to mind is that MAYBE when I am going to the second window xcode is automaticaly releasing my instance of Motion manager.... (CMMotionManager).

Anyone knows how to check this?

回答1:

I hope I understood you right. Then I suggest using a singleton design pattern encapsulating motion manager access in a specialised class. Some pseudo code:

MotionHandler.h

@interface MotionHandler {
    CMMotionManager* motionManager;

    + (MotionHandler*) getInstance;
}

MotionHandler.c:

@interface MotionHandler {

    static MotionHandler* instance;

    + (MotionHandler*) getInstance {
        if (instance == nil) {
            instance = [[self alloc] init];
        }
        return instance;
    }

    - (id)init {
        if ((self = [super init])) {
            motionManager = [[CMMotionManager alloc] init];
            // initialise CMMotionManager
        }
    }
}

So there is one instance of MotionHandler only which manages access to CMMotionManager. You can accesss your CMMotionManager instance from everywhere with MotionHandler.getInstance.motionManager.

If you need access to CoreMotion from several classes, I recommend total encapsulation of CMMotionManager access. That means make it @private and provide methods like getDeviceMotion, setReferenceAttitude, ... This helps to avoid complications like starting it twice or access to CMDeviceMotion before start and makes it more convenient to debug.