I have a noob question regarding how to architect my iPhone app.
I have two main components, a map and an audio player, both self contained classes (MapController and AudioController). I read this great article and am trying to apply it to my app:
http://blog.shinetech.com/2011/06/14/delegation-notification-and-observation/
I have a third class, WebServices, that handles uploading POST data to my server as well as making queries to external API's.
My question:
Do I import header files, and create a new instance of WebServices in both the map controller, and the audio player? And then each controller can reference it's own WebServices for queries?
Or, should I create one WebServices instance on the RootController, and then pass this to the map and audio controllers on init?
In particular, I'm interested in which approach consumes memory more efficiently. Or if it doesn't matter at all.
Thanks!
Consider creating a singleton for your WebServices class and use a shared instance. It seems this is the design pattern you require here.
With regard to the efficiency part of the question, the second option is more efficient purely because you're not storing as much data in RAM. The difference however, assuming your classes are not storing too much internally, is likely to be unnoticable.
#interface WebServices: NSObject
{
}
+ (WebServices*)sharedInstance;
#end
static WebServices *sharedInstance;
#implementation WebSerivces
+ (WebServices*)sharedInstance
{
#synchronized(self)
{
if (!sharedInstance)
sharedInstance = [[WebServices alloc] init];
return sharedInstance;
}
}
#end
Point Zero
Do not resort to singletons, and especially not in multithreaded contexts. You can search this site if you need explanations (hint: the reasons against them are quite similar in OO languages similar to ObjC. e.g. C++, Java, C#...).
To share, or not?
It ultimately depends on the behavior your design needs, but I favor Option #1 as the default.
If you need multiple instances, do not be afraid create multiple (unless you have a really, really, really good reason not to).
If they are heavy to construct, consider what immutable data they can share.
Favor smaller, specialized objects (WebServices may be huge). Smaller objects allow more flexibility and reduce the chances that your program will compete for resources.
What will you gain in this case by sharing? Often, this just increases runtime and implementation complexity... but there can be gains. Without identifying those gains, you should stick to multiple instances to reduce complexity.
Multiple instances allow your program to perform multiple asynchronous requests, based on what they need. Multiple async requests is fine (but it will obviously be slow if you have too many active requests).
Most programs are more logical and easy to maintain when the objects they depend on allow multiple instances (they do not enforce sharing).
Assume multiple instances (1) until have identified a problem. Even after the problem is identified, you can usually avoid sharing.
To determine which consumes less memory requires much more information. If the objects you are considering sharing are not huge (very unlikely), they themselves are not problems wrt memory consumption.
Either approach proposed can result in more memory consumption - it depends entirely on the context and execution. We'll need some more information to answer this specifically.
This is not to imply that sharing is bad, but sharing usually complicates things because you need to design objects to behave predictably when shared (especially since you are operating in a multithreaded context).
Ask yourself:
What significant benefit(s) would sharing WebServices provide?
How would sharing WebServices improve your program and reduce complexity?
It's likely the case that the WebServices map stuff does not interact with the audio stuff. In that case, WebServices may be a good candidate for a base class, where the audio and map services are separate subclasses (assuming the WebServices class is already complex).
I would suggest an NSOperationQueue with a number of NSOperations, instead of a WebServices singleton.
Look at this sweet example from Apple where they do this for concurrent image-downloading. It's a Mac example, but all the classes shown are available on iOS. They use NSInvocationOperation, but you can use an NSOperation subclass, or an NSBlockOperation for cleaner code.
You can add these from anywhere to a single queue, by calling [NSOperationQueue mainQueue]; to fetch the main queue singleton. The singleton's job, in this case, is only to manage the queue (so not too many downloads happen at once), not to do any data processing (that's all handled by your NSOperation).
Related
For my macOS application, I'd like to use concurrent map and queue data structure to be shared between multithread process and support parallel operations.
After some research I've found what what I need, but unfortunately those are only implemented in windows.
concurrency::concurrent_unordered_map<key,value> concurrency::concurrent_queue<key>
Perhaps there are synonyms internal implementations in macOS in CoreFoundation or other framework that comes with Xcode SDK (disregarding the language implementation) ?
thanks,
Perhaps there are synonyms internal implementations in macOS in CoreFoundation or other framework that comes with Xcode SDK (disregarding the language implementation) ?
Nope. You must roll-your-own or source elsewhere.
The Apple provided collections are not thread safe, however the common recommendation is to combine them with Grand Central Dispatch (GCD) to provide lightweight thread-safe wrappers, and this is quite easy to do.
Here is an outline of one way to do it for NSMutableDictionary, which you would use for your concurrent map:
Write a subclass, say ThreadSafeDictionary, of NSMutabableDictionary. This will allow your thread safe version to be passed anywhere an NSMutableDictionary is accepted.
The subclass should have a private instance of a standard NSMutableDictionary, say actualDictionary
To subclass NSMutableDicitonary you just need to override 2 methods from NSMutableDictionary and 4 methods from NSDictionary. Each of these methods should invoke the same method on actualDictionary after meeting any concurrency requirements.
To handle concurrency requirements the subclass should first create a private concurrent dispatch queue using dispatch_queue_create() and save this in an instance variable, say operationQueue.
For operations which read from the dictionary the override method uses a dispatch_sync() to schedule the read on actualDicitonary and return the value. As operationQueue is concurrent this allows multiple concurrent readers.
For operations which write to the dictionary the override method uses a dispatch_async_barrier() to schedule the write on actualDicitonary. The async means the writer is allowed to continue without waiting for any other writers, and the barrier ensures there are no other concurrent operations mutating the dictionary.
You repeat the above outline to implement the concurrent queue based on one of the other collection types.
If after studying the documentation you get stuck on the design or implementation ask a new question, show what you have, describe the issue, include a link back to this question so people can follow the thread, and someone will undoubtedly help you take the next step.
HTH
I'm currently developing an audio application and the performance is one of my main concerns.
There are really good articles like Four common mistakes in audio development or Real-time audio programming 101: time waits for nothing.
I understood that the c++ is the way to go for audio processing but I still have a question: Does Objective-C++ slow down the performance?
For example with a code like this
#implementation MyObjectiveC++Class
- (float*) objCMethodWithOnlyC++:(float*) input {
// Process in full c++ code here
}
#end
Will this code be less efficient than the same one in a cpp file?
Bonus question: What will happen if I use GrandCentralDispatch inside this method in order to to parallelize the process?
Calling an obj C method is slower than calling a pure c or c++ method as the obj C runtime is invoked at every call. If it matters in your case dependent on the number of samples processed in each call. If you are only processing one sample at a time, then this might be a problem. If you process a large buffer then I wouldn't worry too much.
The best thing to do is to profile it and then evaluate the results against your requirements for performance.
And for your bonus question the answer is somewhat the same. GCD comes at a cost, and if that cost is larger than what you gain by parallelising it, then it is not worth. so again it depends on the amount of work you plan to do per call.
Regards
Klaus
To simplify, in the end ObjC and C++ code goes through the same compile and optimize chain as C. So the performance characteristics of identical code inside an ObjC or C++ method are identical.
That said, calling ObjC or C++ methods has different performance characteristics. ObjC provides a dynamically modifiable, binary stable ABI with its methods. These additional guarantees (which are great if you are exposing methods via public API from e.g. a framework) come at a slight performance cost.
If you are doing lots of calls to the same method (e.g. per sample or per pixel), that tiny performance penalty may add up. The same applies to ivar access, which carries another load on top of how ivar access would be in C++ (on the modern runtime) to guarantee binary stability.
Similar considerations apply to GCD. GCD parallelizes operations, so you pay a penalty for thread switches (like with regular threads) and for each new block you dispatch. But the actual code in them runs at just the same speed as it would anywhere else. Also, different from starting your own threads, GCD will re-use threads from a pool, so you don't pay the overhead for creating new threads repeatedly.
It's a trade-off. Depending on what your code does and how it does it and how long individual operations take, either approach may be faster. You'll just have to profile and see.
The worst thing you can probably do is do things that don't need to be real-time (like updating your volume meter) in one of the real-time CoreAudio threads, or make calls that block.
PS - In most cases, performance differences will be negligible. So another aspect to focus on would be readability and easy maintenance of your code. E.g. using blocks can make code that has lots of asynchronicity easier to read because you can set up the blocks in the correct order in one method of your source file, making the flow clearer than if you split them across several methods that all just do a tiny thing and then start an asynchronous process.
In objective-c when you are implementing a method that is going to perform a repetitive operations, for example, you need to choice in between the several options that the language brings you:
#interface FancyMutableCollection : NSObject { }
-(void)sortUsingSelector:(SEL)comparator;
// or ...
-(void)sortUsingComparator:(NSComparator)cmptr;
#end
I was wondering which one is better?
Objective-c provides many options: selectors, blocks, pointers to functions, instances of a class that conforms a protocol, etc.
Some times the choice is clear, because only one method suits your needs, but what about the rest? I don't expect this to be just a matter of fashion.
Are there any rules to know when to use selectors and when to use blocks?
The main difference I can think of is that with blocks, they act like closures so they capture all of the variables in the scope around them. This is good for when you already have the variables there and don't want to create an instance variable just to hold that variable temporarily so that the action selector can access it when it is run.
With relation to collections, blocks have the added ability to be run concurrently if there are multiple cores in the system. Currently in the iPhone there isn't, but the iPad 2 does have it and it is probable that future iPhone models will have multiple cores. Using blocks, in this case, would allow your app to scale automatically in the future.
In some cases, blocks are just easier to read as well because the callback code is right next to the code that's calling it back. This is not always the case of course, but when sometimes it does simply make the code easier to read.
Sorry to refer you to the documentation, but for a more comprehensive overview of the pros/cons of blocks, take a look at this page.
As Apple puts it:
Blocks represent typically small, self-contained pieces of code. As such, they’re particularly useful as a means of encapsulating units of work that may be executed concurrently, or over items in a collection, or as a callback when another operation has finished.
Blocks are a useful alternative to traditional callback functions for two main reasons:
They allow you to write code at the point of invocation that is executed later in the context of the method implementation.
Blocks are thus often parameters of framework methods.
They allow access to local variables.
Rather than using callbacks requiring a data structure that embodies all the contextual information you need to perform an operation, you simply access local variables directly.
On this page
The one that's better is whichever one works better in the situation at hand. If your objects all implement a comparison selector that supports the ordering you want, use that. If not, a block will probably be easier.
I just got into using singletons and I just want to evaluate if I'm using it correctly. I've read that singletons are evil. I've only started with game dev't so things like unit testing and multithreading doesn't reach me yet.
I separated the logic of my game into different modules. Each module has a singleton and non-singleton classes (eg. data model). I'm using the singleton as a mediator so it can interact with other modules. This allows me to work with other people since it's in manageable pieces and I only need to expose the helper methods of my singleton. He doesn't need to know how I implemented it.
Am I doing the right thing?
Examples:
In a traditional japanese SRPG game (like FFTactics), the cells/grid for the tilemap has its own module. The character interacts with the singleton of this module.
All my sprites are generated by an AssetManager (a singleton) which autoscales the sprite depending on the resolution-availability and resolution of the device. This is done just by a calling a method in the singleton.
I definitely don't agree that singletons are evil. They are sometimes overused perhaps but on some occasions are just perfect for the job. In some applications it makes sense to have some kind of general data manager. The singleton pattern is used extensively in the SDK itself (app delegates, shared managers, default centers and so on). Most often these are not "pure" singletons, as in you can access a shared instance but can also create new instances if necessary.
The question you need to ask yourself is whether it would be useful to have access to a single instance of a data manager from anywhere at anytime, if it isn't then a singleton is probably not needed. If you are going to be using singletons in multi-threaded environments however, you do need to worry about race conditions (can one thread modify a resource while another is accessing it), the documentation has good explanations on how best to achieve this in Cocoa.
You could easily do that with an instance too.
Let's say you have a GameMap class and a Tile class. The GameMap represents a 2 dimension grid of Tile objects. (This is your FFTactics example).
GameMap *gameMap = [[GameMap alloc] init];
NSArray *theTiles = gameMap.tiles;
The instance of the GameMap owns the grid of tiles, and creates the tiles when the game map is created. No singleton needed.
You may say "but I only have one GameMap at a time, what's the big deal?". What about loading saved games, or loading new levels? Well that becomes as easy as:
// In whatever class object owns the game map
self.gameMap = [[GameMap alloc] initWithSaveData:saveData];
In conclusion, create an instance of a class that has code to manage other instances of things. Keep as little global as possible and your code will be more scalable and maintainable.
I am creating a simple application using the MVC design pattern where my model accesses data off the web and makes it available to my controllers for subsequent display.
After a little research I have decided that one method would be to implement my model as a singleton so that I can access it as a shared instance from any of my controllers.
Having said that the more I read about singletons the more I notice people saying there are few situations where a better solution is not possible.
If I don't use a singleton I am confused as to where I might create my model class. I am not over happy about doing it via the appDelegate and it does not seem viable to put it in any of the viewControllers.
any comments or pointers would be much appreciated.
EDIT_001:
TechZen, very much appreciated (fantastic answer as always) can I add one further bit to the question before making it accepted. What are your thoughts on deallocating the singleton when the app exits? I am not sure how important this is as I know quite often that object deallocs are not called on app teardown as they will be cleared when the app exits anyway. Apparently I could register the shared instance with NSApplicationWillTerminateNotification, is that worth doing, just curious?
gary
There is a lot of push back on the use of singletons because they are often abused. Lazy coders either (1) don't put enough functionality in the singleton which results in having logic spread out in other objects like spaghetti or (2) they put in to much functionality such that the singleton becomes the entire program. Lazy coders way to often use singletons instead of doing data validation, object testing and object tracking. People get sick of trying to untangle and maintain lazy singleton use so they try to suppress the use of singletons.
I thoroughly understand the impulse and I myself ritualistically warn against singleton abuse.
However, a data model is one of the few legitimate uses for a singleton. This is especially true in small apps like those which run on mobiles. In the end, you will either use a singleton for your data model or you will attach it to a singleton.
For example, suppose you decide to park your non-singleton data model object in the app delegate. Well, you've done this: dataModel-->appDelegate-->application(singleton). To access it, you would call:
[[[UIApplication sharedApplication (a singleton)] delegate] theDataModelObj];
Even if you pass it around like a token from object to object you will still have to have the dataModel obj begin as the property of a singleton.
When an object really does have to meet the "Highlander" pattern ("There can be only one!") then a singleton is the best choice. In addition to the application object, you have user defaults as a singleton as well as the file manager. Clearly, in all three cases, you want one and only one instance in existence for the entire app. For example, if you had more than one user defaults object, your app would be a train wreck trying to track all the preference settings. If you have more than one file manager, file operations could step on one another.
A properly designed user data model is just a larger version of user defaults. It should be the only object that directly manipulates the user's data. No other object in the app should have that task in the least. That makes the singleton design pattern the best one to use in this particular case.
Singletons are a very powerful tool but just as with a physical tools, the more power they give you, the more opportunities they create for you to cut you head off if you use them carelessly. For this reason, a singleton should seldom be your first choice. There are usually better design patterns to employ.
However, when you really need a singleton, you shouldn't shy away from using them just because the laziness of others has given them a bad rep.
Knowing when and when not to use a powerful and dangerous tool is part of the programmers intuition you develop with experience. You can't go by formula. It is one of those factors that makes good coding an art and the programmer a craftsman.