If I have a tab bar app, and plan on using Core Location in different tabs, is there a good common place to put the code used to alloc/init the CLLocationManager, and get the updates once startUpdatingLocation is called? Or if it's going to be used in two different tabs, do I then just put it in the code for each tab? Just wondering what best practices are since I am new to programming. Thanks.
I don't agree with John, the AppDelegate is the "easy" way to do it, but not always the better.
I would do this with a singleton. You can look at Matt Gallagher's article on Singletons, AppDelegates and top-level data for reference.
if you notice you're duplicating what you've written, or faced with writing code which exists, consider creating an interface (object, set functions, etc.) to handle these tasks.
see DRY (do not repeat yourself). there will be a lot of duplicate functionality by the time you've written a few apps. it's best to write it once, and to write that correctly.
here are some high level guidelines:
don't put app-specific features in a common interface (instead, use a subclass shared by the 2 projects)
always keep your bases free of hacks (unless you're dealing with an issue in the system libraries). if clients (e.g., subclasses, callers) need a particular workaround or require a specific check, then it is better to make them handle it.
use assertions to ensure they use the interface as intended, check every argument, precondition/postcondition, the state of your object, etc..
keep your objects/interfaces very small and maintainable, with a clear purpose of their intended use. naturally, this will result in a higher number of objects.
avoid the urge to use singletons and static data; there's almost always a better way even if it's as simple as forcing clients to create an instance of your class.
create libraries with these interfaces, and divide them logically.
now that that's covered…
i'd begin by using (potentially multiple) instances of the objects you'll need. there is nothing in the documentation that states "you should not create multiple instances of the object".
if this is somehow inadequate in profiling, then consider using a shared object which relays messages to the objects (in your app) which need updates.
rationale: chances are, apple's already optimized the implementation, so you don't have to.
finally, i broke these guidelines in an app which required a ton of location requests, and displayed a ton of location information. the app used some static data behind an interface which stored the location manager and the location (among other things). so i ended up using static data with private (hidden) static data to reduce the memory and cpu demands in this case.
The App Delegate is a good, central place for such data. You can always get to the app delegate with [[UIApplication sharedApplication] delegate]
Related
I want to ask that i made a class which has more than 100 static methods. But class is not static, so i want to ask that do all methods live in application memory whole time or not. Or it is bad programming. please suggest me.
Please solve my issue.
Does it have any non-static method also?
if No, class should be made static.
if yes, i'll say design can be improved.
And all methods are loaded into application memory as soon as class is first used. however only one copy of methods are kept in memory.
If you really want these programs available in a reusable context, then write them as regular external C or C++ functions and add them to a library to use in other projects. Then reintroduce or wrap them as needed. I know - it's not a popular answer among objc devs, but at least it scales much better when you begin to have really complex codebases.
But class is not static, so i want to ask that do all methods live in application memory whole time or not.
Yes, and these methods may not be stripped. When you use these in other projects, you pay for everything. With functions, they may be stripped and you only pay for what you actually use in the program. Specifically, the memory of a function or method exists in the binary and in the program's memory only once - instances do not clone methods, they are referenced and looked up using a dispatch table in the runtime (like a vtable). Each instance of the class only accesses its selectors via this table so method count does not make an instance larger. Memory in this case is rarely (if ever) a concern.
Or it is bad programming. please suggest me.
This is very unusual, and an indication that something has gone wrong in the design.
I'm new to Core Data, and I'm trying to make sure that I've got my data model and its usage set up properly.
I basically have two file types in my App ... one contains settings type data and a second contains data sets that the user will be working with (kind of like documents, although I can imagine the user working across 10s or even 100s of these files simultaneously).
I've been reading books on Core Data, and I remember reading that typically an app has a single NSPersistentStoreCoordinator, a single NSManagedObjectContext and a single NSManagedObjectModel.
I currently have a single managed object model with configurations for the various file types I have. I had been planning on also having one of the NSPersistentStoreCoordinators / NSManagedObjectContexts, and when I create new Core Data objects, I would make sure that each one was added to the correct persistent store.
However, I've seen examples where each file has its own NSPersistentStoreCoordinator and NSManagedObjectContext.
Are there advantages and disadvantages to having multiple NSPersistentStoreCoordinators and NSManagedObjectContexts in a single thread application?
Initially, I had been hoping to be able to move objects from one persistent store to another during user cut and paste type edits, but that doesn't seem possible either way.
Any advice is greatly appreciated!
Edit
Here is some more information about what is confusing me. When I read the documentation about NSPersistentStoreCoordinator, it says:
The coordinator is designed to present
a façade to the managed object
contexts such that a group of
persistent stores appears as an
aggregate store.
In my case, this is not what I want. I want my documents to be perceived as separate documents, and I don't want the queries to be confused between each other.
In addition, with only one persistent store coordinator and many persistent stores, if I forget to assign an entity to the correct store on creation, I find myself with bugs since entities are arbitrarily assigned to a valid store when they are created. I'm not sure what would happen with relationships that point to objects in different stores (probably an assertion failure?).
To me, it seems that having a single context / persistent store coordinator per store would be less prone to bugs, and allows me to keep the data for each document isolated from each other.
The only thing that a single persistent store seems to buy me is that I can perform a save operation for all stores simultaneously which would be preferable. With multiple contexts / store coordinators, I would need to perform separate save operations.
If you use the OSX NSPersistentDocument class, it seems to enforce a separate context / store coordinator per document.
Anyway, from all my research, it seems that separate store coordinators / contexts would work better for my App, but the reason I posted this is because I am new to Core Data and this approach does seem to go against the recommended flow and I'm worried that I'm missing some gotchas that will come back to bite me.
More Thoughts / Information
As I think about this more and read more feedback from others (thank you everyone!!!), my current thoughts are as follows.
For myself, there really doesn't seem to be that much difference between the two approaches and I currently believe that I could make it work well either way.
With a single store coordinator, I need to make sure that newly created entities are attached to the correct store (not really a big deal). With multiple store coordinators, I need to make sure that newly created entities are added to the correct context (of which I will have many of them). With the way my code is structured, either approach should be relatively easy for me.
I personally want to search a single store at a time. If I have multiple store coordinators, this is automatic. If I have a single store coordinator, I need to make sure to constrain the fetch request. (either way, not really a big deal).
The documentation for the store coordinator implies that its advantage is making multiple stores appear as one. For my app, I do not need or want that so this is not really a consideration for me (although if I wanted to add cross-store searching capabilities in the future, it would be best to keep everything in a single store coordinator).
To me, none of the above reasons are really good arguments either way, and if they were the only arguments, I would probably try to do things the more conventional way and stick with a single store coordinator.
However, one final reason (and the main reason that I originally posted this question) is that I am planning on taking advantage of some features in iOS 5 that seem to require multiple store coordinators. I want to be able to weak-link my app to be backwards compatible, so it seems that having my iOS 4 code closely resemble the iOS 5 code would be preferable.
The more I think about this, with the support for multiple OS versions, I could probably still implement things either way with the correct abstractions.
Thank you everyone for your feedback! I'm slowly getting the hang of Core Data which has mostly been a great experience, although its given me my share of headaches as well!
Generally an app will use only one PersistentStoreCoordinator and it is initialized in app delegate.
For more details and clarification please check the apples doc on Core Data
I can't honestly think of a reason why you would want to have a second coordinator unless you are performing some pretty serious concurrent, multi threaded tasks on the same model. From what you described above, you may only need to create a separate context for certain managed objects, or possibly separate stores if you need them to be completely independent.
You will hardly ever interact directly with a persistent store coordinator as most of your operations are done on the context level and then persisted when you are ready (again via context) through the store coordinator.
You've obviously done your own research so I am not going to tell you to check documentation XYZ (Core Data is well documented for basic level stuff but anything slightly more advanced and you are on your own), but my main point is that having a separate store coordinator for each of these models will probably increase the complexity of your code instead of making it easier to manage which seems to be your main motivation in the original question.
I don't see any real technical limitation to having multiple NSPersistentStoreCoordinator instances in your app as long as they are all pointed to a unique location on disk.
However, taking that approach is definitely not common and is going to add a lot of complexity to your app that may not be necessary. From what you've described about your data model, I don't see any reason why you'd need multiple NSPersistentStoreCoordinators.
Be sure to read the CoreData Programming Guide and know that you'll need to create a unique NSManagedObjectContext per thread, rather than per NSPersistentStoreCoordinator as you described in your question.
It seems a lot of Objective-C code is using Singleton nowadays.
While a lot of people complaining about Singleton, e.g. Google (Where Have All the Singletons Gone?), their fellow engineers also use it anyway: http://code.google.com/mobile/analytics/docs/iphone/
I know we had some answers in Stack Overflow already but they are not totally specific to Objective-C as a dynamic language: Objective C has categories, while many other languages do not.
So what is your opinion? Do you still use Singleton? If so, how do you make your app more testable?
Updated: I think we need to use codes as example for more concrete discussion, so much discussions on SO are theory based without a single line of code
Let's use the Google Analytics iOS SDK as an example:
// Initialization
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-0000000-1"
dispatchPeriod:kGANDispatchPeriodSec
delegate:nil];
// Track page view
[[GANTracker sharedTracker] trackPageview:#"/app_entry_point"
withError:&error];
The beauty of the above code is once you have initialized using the method "startTrackerWithAccountID", you can run method "trackPageview" throughout out your apps without passing through configurations.
If you think Singleton is bad, can you improve the above code?
Much thanked for your input, have a happy Friday.
This post is likely to be downvote-bait, but I don't really understand why singletons get no love. They're perfectly valid, you just have to understand what they're useful for.
In iOS development, you have one and only one instance of the application you currently are. You're only one application, right? You're not two or zero applications, are you? So the framework provides you with a UIApplication singleton through which to get at application-level os and framework features. It models something appropriately to have that be a singleton.
If you've got data fields of which there can and should be only one, and you need to get to them from all over the place in your app, there's totally nothing wrong with modeling that as a singleton too. Creating a singleton as a globals bucket is probably a misuse of the pattern, and I think that's probably what most people object to about them. But if you're modeling something that has "singleness" to it, a singleton might well be the way to go.
Some developers seem to have a fundamental disgust for singletons, but when actually asked why, they mumble something about globals and namespaces and aesthetics. Which I guess I can understand, if you've really resolved once and for all that Singletons are an anti-pattern and to be abhorred in all cases. But you're not thinking anymore, at that point. And the framework design disagrees with you.
I think most developers go through the Singleton phase, where you have everything you need at your fingertips, in a bunch of wonderful Singletons.
Then you discover that unit testing with Singletons can be difficult. You don't actually want to connect to the database, but your Singleton does. Add a layer of redirection and mock it.
Then you discover that unit testing isn't the only time you need different behaviour. You make your Singleton configurable to have different behaviour based on a parameter. You start to wonder if you need to split it into two Singletons. Then your code needs to know which Singleton to use, so you need a Singleton that knows which Singleton to use.
Then some other code starts messing with the values in your Singleton, while you're using it. How dare they! If you wanted just anybody to get at those values from anywhere, you'd make them global...
Once you get to this point, you start wondering if Singletons were the right solution. You start to see the dangers of global data, particularly within an OO design, where you just assume your data won't get poked at by other people.
So you go back and start passing the data along, rather than looking it up (this used to be called good OO design, but now it has a fancy name like "Dependency Injection").
Eventually you learn that Singletons are fine in moderation. You learn to recognize when your Singleton needs to stop being single.
So you get shared objects like UIApplication and NSUserDefaults. Those are good uses of Singletons.
I got burned enough in the Java Singleton craze a decade ago. I don't even consider writing my own Singletons. The only time I've needed anything similar in recent memory is wanting to cache the result of [NSCalendar currentCalendar] (which takes a long time). I created a category on NSCalendar and cached it as a static variable. I felt a bit dirty, but the alternative was painfully slow code.
To summarize and for those who tl;dr:
Singletons are a tool. They're not likely to be the right tool, but you have to discover that for yourself.
Why do you need an answer that is "total Objective C specific"? Singletons aren't totally Obj-C specific either, and you're able to use those. Functions aren't Obj-C-specific, integers aren't Obj-C specific, and yet you're able to use all of those in your Obj-C code.
The obvious replacements for a singleton work in any language.
A singleton is a badly-designed global.
So the simplest replacement is to just make it a regular global, without the silly "one instance only" restriction.
A more thorough solution is, instead of having a globally accessible object at all, pass it as a parameter to the functions that need it.
And finally, you can go for a hybrid solution using a Dependency Injection framework.
The problem with singletons is that they can lead to tight coupling. Let's say you're building an airline booking system: your booking controller might use an
id<FlightsClient>
A common way to obtain it within the controller would be as follows:
_flightsClient = [FlightsClient sharedInstance];
Drawbacks:
It becomes difficult to test a class in isolation.
If you want to change the flight client for another implementation, its necessary to search through the application and swap it out one by one.
If there's a case where the application should use a different implementation (eg OnlineFlightClient, OfflineFlightClient), things get tricky.
A good workaround is to apply the dependency injection design pattern.
Think of dependency injectionas telling an architectural story. When the key actors in your application are pulled up into an assembly, then the application’s configuration is correctly modularized (removing duplication). Having created this script, its now easy to reconfigure or swap one actor for another.”. In this way we need not understand all of a problem at once, its easy to evolve our app’s design as the requirements evolve.
Here's a dependency injection library: https://github.com/typhoon-framework/Typhoon
How can I make the reachability work as a singleton?
Here is what I want to do ...
I have an application.
When it launches I want to have a singleton and work with the reachability in order to hold the network status.
Then I want from other controllers to access the singleton and check the network status.
For example I want every time user clicks on one tab and the screen is shown to check the internet status and enable or disable a button.
I know the question is very generic but I am so confused.
I am currently using reachability 2.2
Any tips or ideas or even guides will be appreciated.
And a final question....
how 'moral' is the singleton usage? And is it the best practice to be more close to MVC model?
Thanks again
Singletons are fine. Reachability can be a very sensible singleton. You should be aware of the doc "Creating a Singleton Instance" in Apple's Cocoa Fundamentals Guide, but read the text carefully. The code they present is seldom what you need and can cause more problems then it solves. It is only appropriate in cases where it is wrong for there to be multiple copies of the object (wrong because the object manages a unique resource for instance). In those cases, I tend to prefer asserting in -init rather than overloading allocWithZone: because I'd rather force the developer to make the correct call (+sharedInstance) rather than quietly fix it for them, and have them think they've created two instances when there is actually one (at least in cases where the singleton is mutable or holds state).
There is an excellent discussion of good singleton patterns in this question. I favor #Robbie Hanson's answer in my own code because it is cheaply thread-safe.
I've been playing around with iOS development and I'm getting to the stage where I want to create something beyond a simple app. However, I'm not confident that I understand how to partition an application correctly.
For the purposes of simplicity, imagine a (very) simple audio player application. Let's say there are two view controllers, accessible via a UITabBarController which is instantiated the main AppDelegate class.
Each of these view controllers has the following responsibility:
PlayerViewController - A sound player which plays the “current” audio sample when the user presses a button.
SelectorViewController - A sample selector, that uses a UIPickerView to display the available audio samples so that the user can select which sample they want to play.
So far, so good. However, what I don't quite understand is where I should store the data on the available samples, so that both of the views can find out information on the available samples, trigger a sample to play, etc.
As both view controllers need to access this “model level” information, would creating an “audio manager” singleton class be a sensible approach, or is there (much, much more likely I'm guessing) a better means of solving this problem that I'm overlooking.
Any pointers would be much appreciated.
I've used this pattern (Singleton data manager) several times in serious apps. It's quite straightforward, easy to understand, easy to use, although this pattern is despised by OOP purists.
If nobody tells you it's wrong to use a singleton, go ahead, just be sure to check Apple's documentation on the recommended implementation (there is a bunch of methods to overload).
Oh and BTW, Apple uses it a lot in the iOS SDK, so it's a common practice (see class methods beginning with 'shared').
UPDATE:
Another possibility is reusing an already existing singleton, the Application delegate for instance. It might feel cleaner, or not, it's more a matter of taste. It has the advantage of giving a clear "entry point" where you allocate/create/init your data manager.
If the source of your data is in a remote server and it comes to your app as an XML file, you can also get it whenever you want with a kind of source downloader class.
That way you don't have to care about keeping things in memory when they are not necessary. Just get it from the remote source, parse it and then release it.
Another way of achieving this more careful use of memory is to get your data from a sqlite database using Core Data. But some people thinks it is too much complicated for a simple app and prefer running queries by hand.