correct method to create global variable in iphone sdk? - iphone

is there any best method to maintain global variable in iphone sdk? if i change it, it will affect in all controllers,views of that iphone application?

Globals are currently considered ugly, but they are a type of unprotected pre-allocated pre-initialized singleton, and all there was in computer programming best practices 50 years ago (1st edition of Knuth's books, etc.). The best method of maintaining globals includes using a lot of very clear comments so that you can consider something else when it's time to make the code more modular and reusable (potentially at some cost in code size).
To answer the OP's question, if you modify a global, then any controllers or views (and any C or Objective C code in the same thread that doesn't "cover" the globals name) that reads that global will get the newest value. But that new value won't be "pushed" immediately. Those views or controllers won't notice any new value until some method eventually is called that actually reads the global variables.
If you need a view or controller to respond faster, then you will need notifications or key-value observing rather than just modifying a global variable.

Globals are ugly. Better to use a singleton "Data Manager" class that contains all your data, and then use either notifications or key-value observing to update your ViewControllers about changes.

Related

asp.net mvc accessing class fields from a custom auth attribute

I am using a custom AuthAttribute to determine whether a user can access a controller and/or actions. The problem is I have to duplicate information and EFx connections in the attribute that already exist on the class that is being adorned.
My question is whether there is a way to access the fields on the adorned class from the custom AuthAttribute? I am trying to avoid having to re-architect the software in a way that would provide a single point of access since that would open up a different can of worms.
I believe I have found an answer that works. I welcome all comments on this solution.
Rather than have the attribute gain access to the properties and fields on the controller it adorns you can share values between them in a thread-safe way through the common HttpContext object. So if you are being extreme like I am and are trying to cut down on duplicate calls to your database in both the authattribute and the adorned controller action then pass the results forward. What that means is the authattribute will be called first and you can stash the retrieved values in the "Items" collection off the HttpContext object passed into the AuthorizeCore(..) method. You can then retrieve the same value in a THREAD-SAFE way through the HttpContext object in the controller.
example to save value within the AuthorizeCore(..) override of the AuthAttribute:
httpContext.Items.Add("fester", "bester");
example to retrieve value inside the subsequent call to the Controller/Action:
this.HttpContext.ApplicationInstance.Context.Items["fester"];
I have to warn you this is only a possible implementation that appears to work in simple testing. Personally it feels like a hack and there has to be a better way. I would also state this is in pursuit of a dubious performance benefit. It should cut down on the number of database and/or network calls by cache'ing retrieved data in the HttpContext so you don't have to repeat the calls in both the authattribute and the adorned Controller/Action. If you don't have a web site that gets a huge volume of calls then I would warn you against this.
I hope someone recommends something better on this page. I will keep an eye on how this works on my web site and let y'all know if it behaves and is truly thread-safe.

iOS Asynchronous NSURLConnection triggering behaviors on different views than the one that call it

Me and my team are currently rookie developers in Objective-C (less than 3 months in) working on the development of a simple tab based app with network capabilities that contains a navigator controller with a table view and a corresponding detailed view in each tab. The target is iOS 4 sdk.
On the networking side, we have a single class that functions as a Singleton that processes the NSURLConnection for each one of the views in order to retrieve the data we need for each of the table views.
The functionality works fine and we can retrieve the data correctly but only if the user doesn't change views until the petition is over or the button of the same petition (example: Login button) is pressed on again. Otherwise, different mistakes can happen. For example, an error message that should only be displayed on the root view of one of the navigation controllers appears on the detailed view and vice versa.
We suspect that the issue is that we are currently handling only a single delegate on the Singleton for the "active view" and that we should change it to support a behavior based on the native Mail app in which you can change views while the data that was asked for in each one of the views keeps loading and updating correctly separately.
We have looked over stackoverflow and other websites and we haven't found a proper methodology to follow. We were considering using an NSOperationQueue and wrapping the NSURLConnections on an NSOperation, but we are not sure if that's the proper approach.
Does anyone have any suggestions on the proper way to handle multiple asynchronous NSURLConnections to update multiple views, both parent and child, almost simultaneously at the whim of the user's interaction? Ideally, we don't want to block the UI or disable the buttons as we have been recommended.
Thank you for your time!
Edit - forgot to add, one of the project restrictions set by our client is that we can only use the native iOS sdk network framework and not the ASIHTTPRequest framework or similar. At the same time, we also forgot to add that we are not uploading any information, we are only retrieving it from the WS.
One suggestion is to use NSOperations and a NSOperationsQueue. The nice thing about this arrangement is you can quickly cancel any in-process or queued work (if say the user hits the back button.
There is a project on github, NSOperation-WebFetches-MadeEasy that makes this about as painless as it can be. You incorporate one class in your classes - OperationsRunner - which comes with a "how-to-use-me" in OperationsRunner.h, and two skeleton NSOperations classes, one the subclass of another, with the subclass showing how to fetch an image.
I'm sure others will post of other solutions - its almost a problem getting started as there are a huge number of libraries and projects doing this. That said, OperationsRunner is a bit over 100 lines of code, and the operations about the same, so this is really easy to read, understand, use, and modify.
You say that your singleton has a delegate. Delegation is inappropriate when multiple objects are interested in the result. If you wish to continue using a singleton for fetching data, you must switch your pattern to be based on notifications. Your singleton will have responsibility for determining which connection corresponds to which task, and choosing an appropriate notification to be posted.
If you still need help with this, let me know, I'll try to post some sample code.

Delegates and Notifications in Objective-C

In my AppDelegate, I download some data from a JSON feed. I am downloading a now/next/later schedule for a few channels. I have three different view controllers for each now, next and later. In each view controller, a user can add/remove the channels so when that happens, the newly added channel data has to be downloaded again.
Since the data is downloaded in the AppDelegate and stored there, how would I pass it to the three view controllers? Should I implement three separate delegates? Keep in mind that when adding a new channel, its data has to be downloaded again (which I am doing outside the AppDelegate now).
Any help please?
Thanks
This is basically a matter of style and your approach isn't invalid as such.
I'd do it another way, though - the AppDelegate is not meant to be used as a workhorse and having several AppDelegates at the same time is simply impossible.
Here are some thoughts about how this could be done (though it's of course not the only proper way):
First, I'd employ Core Data or some other sort of storage which is available from anywhere within your app.
Then maybe I'd introduce some sort of "data controller" class (maybe a singleton). This class should handle both download of data and the distribution of that data to your viewcontrollers as requested.
By having one central controller for that purpose, you'd ensure that data gets downloaded only once because the controller knows exactly which data is already in stock.
Your viewcontrollers would neither be responsible for managing downloads anymore nor would they access the data on disk by themselves. They'd just make a request to your data controller and get a callback when the requested data is available - no matter if it was on disk already or has been downloaded for the occasion.
This keeps your VCs slim and focused and reduces the pain of making changes to your interface.
Toastor's answer is correct and as he says, there are several ways to do this. One is to call a data access class and change the values OR listen for changes on the values. For the later, the Key-Value Observing Programming Guide says the following:
KVO is particularly useful for communication between model and
controller layers in an application.
A controller object typically observes properties of model
objects, and a view object observes properties of model objects
through a controller.
In addition, however, a model object may observe other model
objects (usually to determine when a dependent value changes) or even
itself (again to determine when a dependent value changes).
Another is to make the dependency explicit, maybe passing a data access class saved in your app delegate. See Object-oriented design question, iPhone.

How does one communicate between view controllers in a UINavigation type application?

I have a UINavigation based application that gathers information on various screens and eventually makes a web service request using all the parameters collected.
So I have A,B,C,D view controllers. A gets the name & number, it then pushes B onto the screen with some basic info ETC ETC until it gets to D where I actually fire off the web service.
The poor method I have been using is to duplicate class fields from A onwards. Meaning if I collect name, and number, then I make those the fields of B, which then adds a few fields, and then C has class fields of both A & B which seems like a poor programing practice.
What can I do to get access to class A's fields in class D? I have gotten certain ideas but not sure how valid they are.
1). Use NSNotification (Is this overkill?) If so how do I pass fields?
2). DO I just retain all 5 view controllers and just get the info at the end? (seems very inefficient)
3). Should I just instantiate a NSObject class called Payload and just set its fields every time I bounce from one view controller to the next? (If so do I create it in class A? What if user navigates back to class A, will it then get reset ETC ETC)
As you can tell I have tried to find a solution and I am fairly new to it. Some detailed suggestions would be highly appreciated.
Depending on situation, there are several ways that seem appropriate.
Get to know MVC Design Pattern
Classes are not data storage. If class doesn't have interface to interact with represented object, excluding accessors, you're doing it wrong.
3.
I have a UINavigation based
application that gathers information
on various screens and eventually
makes a web service request using all
the parameters collected.
So, your web request is based on parameters gathered from various views. Why not create an
model of said request? MyRequest or something like that :) Or several more specific variants, sharing common parent class? This generator holds logic, gathers data and parameters as you advance trough views and provides NSUrlRequest at the end to WebView or maybe different kind of object which is NSURLRequest delegate and conforms to UITableViewDataSource/Delegate protocols to be used to display downloaded data.
I'd go for 3) and yes you should create it at the beginning (Class A).
But maybe user go back to Class A to change the value on purpose so resetting it doesn't seem to be a problem.
Why not use a singleton object and pass it around?
The advantages of this method are:
There's only one instance whose
reference is being passed around
between viewcontrollers
Changes you
make are reflected the next time you
access this object from another view
controller
And to answer one of your questions, NSNotification allows us to pass objects along....
Here's a good example on singleton objects in iOS by Matt Galloway. It's the one I always refer to:
http://www.galloway.me.uk/tutorials/singleton-classes/

Is this all for Garbage Collection in Objective-C?

Hi I just picked up Obj-C and quite dislike its manual memory management.
I decide to go with its Garbage Collection, by adding
objc_startCollectorThread();//garbage collection
in my Main() and change the garbage collection value to [-fobjc-gc]
So is that all I need? So I can program "freely" like I do in Java/Python..etc?
Yes you are right, but in case any iPhone programmer comes by and thinks "oh sweet!", please note that the iPhone doesn't support Garbage Collection yet (ever?). So this is the MacOS only solution.
Note that -fobjc-gc means that you still use retain/release (when writing a Framework/library); you probably want -fobjc-gc-only if you want to get rid of the reference counting code completely.
As other said, there is no garbage collection in iPhone.
If you are writing a Desktop Cocoa app, all you need is the -fobjc-gc-only flag, without the explicit objc_startCollectorThread() startup function.
Basically, yes. This is covered in Apple's documentation. You may also need occasional calls to
objc_clear_stack
But this is optional, to ensure stack retained object lifetimes are as short as needed.