I have a lot of one-to-many notification needs in my app, so I'm constantly posting notifications for other objects to receive.
I was curious if anyone has a good method for debugging the contents of the default notification queue, aside from putting print statements in all my selectors. I'm sure I have a lot of functions that are called multiple times because I forget to remove them from the queue and add duplicates. I just need a good way to go through everything and figure out which ones are the culprits.
Related
I have been doing a great deal of work using Notifications in few of my apps, at first they gave me random crashes but then I learned about the best way to use NSNotifications and here are a few best practices that I learnt.
---remove the observe's when they are of no use.
---remove the observer's before they are deallocated, leads to random crashes.
---Do not add two observers methods in the same class for the same notification.
If I am wrong or If I miss anything feel free to add up. What I want now is when I post a notification can I see the list of observer's waiting to receive my notificaton and can I selectively post to a set of observer's by missing out some intentionally?.
I also saw this Thread that is quite similar. I am creating a new thread because I want to dig up more with Notifications. I expect good contributions.
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.
So I'm working on this application that requests and retrieves webservice content for iPhone. The problem I am running into is this: When I initially request data, it is spawned off as an independent thread so that the application does not become unresponsive due to the network being slow. What this means is that if the user navigates away from the current page before this data finishes downloading, unexpected things can happen.
I have managed to narrow down the problem cases to one relatively simple one: I have some nested tables, so if a user goes down into the "Messages" table, which can sometimes take a little while to download, then back out immediately, and select a different set of messages to view, the previous set of messages ends up loading, because it was still in the queue.
Here are things I have tried:
1) I tried cancelling the operations, but this is futile, because since I only allow one operation in the queue at the time, it triggers immediately
2) I tried validating that the recipient of the data is the same, but this doesn't work because the actual table object is the between the two selections, it just needs a different data set.
Anyone have any general programming suggestions on how to solve this tricky threading problem?
On an iPhone specific note: if I could just stop the user from being able to back out of the messages table, I wouldn't have this problem, because they would basically be locked into that view until the data has finished loading.
Thanks!
This post has some design advice relating to iOS networking and threading. The basic gist of it is "Don't use explicit threading", and I couldn't agree more. NSURLConnection has great built-in functionality for asynchronously loading data from a URL while managing all of the threading for you. They can also be cancelled easily at will.
If you were to use the NSURLConnection paradigm, you can simply cancel any pending request when you back out of the requesting view controller.
iPhone Development:
I want to have an infinite loop constantly checking an NSMutableArray and if [size > 0] pull the first object, do something with it, remove it, wait .25 seconds, then continue checking.
I want my GUI buttons to add this list. Is there a way to do this? Is there a way to do this by having the loop in the main thread?
UPDATE
I guess i didn't ask the question properly. I'm using the AsyncSocket class to send telnet commands. I need to send them fast because their used to control a RC car, however the RC receiver is a tad slow. So i want to slow downs the rate in which my iPhone sends out the commands. Right now i have button events sending out the commands but i want to instead have the events add the command to a list/queue/array. In parralel to the button clicks I want a process to check the queue every .25 seconds and send out the commands in the queue.
MY PROBLEM:
the AsyncSocket isn't thread safe so I cannot have another thread sending commands. The documentation reads
If you find yourself on a thread which
is different from the thread on which
AsyncSocket is running, and you need
to invoke a method on AsyncSocket,
then you must use a method like
performSelector:onThread: to ensure
the method is invoked on AsyncSocket's
thread (and thereby maintaining
thread-safety)."
I dont know what this means...
What does this quote above mean?
Is multithreading required for what i want to do?
I would recommend looking into Key Value Observing. This will allow you to set up an observing class to be notified when entries are made into the array.
It'll be a bit harder than the standard tutorials you'll find, most simply observe a property being updated. You'll need to use -willChange:valuesAtIndexes:forKey: and -didChange:valuesAtIndexes:forKey: when you add elements to the array. If all you need to listen for is items added, this should be enough. However, you can look into ObservingOptions to really get finer control.
See more about NSKeyValueObserving here: http://developer.apple.com/library/ios/#documentation/cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/occ/cat/NSKeyValueObserving
This method will allow you to not waste any cycles polling for changes.
This is easily solved by using an NSOperationsQueue.
add an NSTimer with interval 0.25 that will be cheking it in a loop.
Check documentation. There are some useful sample-projects
Just to give background for my situation, I have a manager singleton that pulls data from a webserver and provides access to the downloaded data. I have several types of views that will consume this data, but only one view at any time will need to receive events.
I was just wondering what people prefer to use when they need to get events from a singleton. Do you use NSNotificationCenter, Target/Action, or delegate?
Thanks for any help.
Are you really, really sure only one view needs to receive events? For instance, you don't have a master view that would need access to the same update that a subview was notified about?
If you truly have only one view controller needing updates at a time ever, I might use a delegate approach. Here's something to consider - what happens if you are in the middle of receiving an update and the user change screens... is that OK? would you cancel the request?
Anything more than one, or if that in-flight changing delegate scenario has issues, then you may well be better off with a notification that anyone can hook into. It's best to keep the notification light with some kind of reference to the change and have the receiver have to look up the altered data.
If there are going to be a large number of events, then you want to stay away from NSNotifications.
For the least amount of overhead I would go with the delegate pattern, although I don't think that target/action has much more overhead than delegates.
Try your favorite way and if there is a problem profile or try a different approach.
I usually start with the easiest to get implemented. For example I once tried to use notifications for some interface code I had written years ago but with 30-60 updates/second the whole interface bogged down unacceptably so I went with delegates which fixed the problem.