Question

I have a Game class that has a -(void) play method which will be executed when the user clicks on the Play button on the device.

Inside the -(void) play method I have a while loop that will be executed repeatedly until the user clicks on the Quit button. This while loop is basically the core of my code, where all necessary methods are being called, things happen, objects interact etc.

I also have a User class (amongst other classes..) and I create a User* player instance in the -(void) play method of my Game class to store some values and have those interact with other things along the duration of the game..

Now I need to know (at any moment during the game..) the device's deviation from the magnetic North & the acceleration the user is exercising on the device

I've written the code and everything is working fine. However, being new to programming I have a few questions concerning the overall design of my code, which I think is a mess especially when it comes to using the CoreLocation & CoreMotion frameworks..

The -(void) play method of the Game class (which is basically my "main" method) is executed on a separate thread as in [game performSelectorInBackground:@selector(play) withObject:nil]; Is this the right way to do it?

However, I initialise CoreMotion Acceleration updates from inside the -(void) play method as in [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]withHandler:^(CMDeviceMotion *motion, NSError *error){...} which means that updates will be stored in the main Queue whereas the method initializing these updates is executed from inside a method(-(void) play) that runs on a separate thread. Does that make sense?

I also initialise CoreLocation updates when I initialize an instance of my Game class. Even more weird?

My point is this. Given that I'll be measuring the acceleration the user is exercising on the device and the orientation he/she is giving to the device (degrees) I want to encapsulate all that in my User class and have methods like [player getMyDegrees]; and [player getMyAcceleration]; Isn't this the correct way design-wise? Where exactly should I initialize those updates? From inside which specific class-method? Should everything be running on the same main thread or the same separate thread or on different separate threads? I'm confused..

Was it helpful?

Solution

Threading is a complex issue, as you've no doubt seen.

The -(void) play method of the Game class (which is basically my "main" method) is executed on a separate thread as in [game performSelectorInBackground:@selector(play) withObject:nil]; Is this the right way to do it?

It depends. Is there any work that you are doing in the -play method that absolutely must be taken off the main thread (i.e. crazy number crunching, server requests, loading textures, etc.) so as to make the UI more responsive? That's really the only reason methods are dispatched to the background on iOS, is to maintain a responsive UI, because UIKit classes are not just thread-unsafe, but they will wholeheartedly dive straight off a cliff and take your app with them if you try to do anything in the background.

However, I initialise CoreMotion Acceleration updates from inside the -(void) play method ... which means... these updates are executed from inside a method(-(void) play) that runs on a separate thread. Does that make sense?

Well, again it depends here. The ultimate goal of threading is not to have two or more threads attempt to access or mutate one object held by another thread, which is just the start of a whole mess of problems. The one thing that I have to take issue with is the fact that you are using the main queue despite a very clear and ominous warning in the documentation:

Because the processed events might arrive at a high rate, using the main operation queue is not recommended.

This is an example of one of those high powered calculations that you should be throwing to a background thread, which is NSOperationQueue's forte.

I want to encapsulate all that in my User class and have methods like [player getMyDegrees]; and [player getMyAcceleration]; Isn't this the correct way design-wise? Where exactly should I initialize those updates? From inside which specific class-method?

It depends on how design-wise you're trying to be, and what you consider good design. Good code is usually code that you could hand off to another programmer and have them pick up where you started off with very little effort. That being said, it sounds like your user class is going to be the controller part of MVC. If your classes are too bulky, cut 'em up. Classes in objective-c are surprisingly light-weight creatures. Even arranging one class in multiple categories that describe the general section's implementation are fine (the header of NSString for example).

Should everything be running on the same main thread or the same separate thread or on different separate threads? I'm confused..

Everything UI and light should be running in the main thread (or main queue if that's how you prefer to look at it), and everything heavy and thread-blocking should be put in a background thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top