Is it safe to use the "hash" method to track NSURLConnections in memory? - iphone

My question is related to this discussion: http://www.cocoabuilder.com/archive/cocoa/202211-how-to-get-nsurl-form-nsurlconnection.html
I am sending several NSURLConnections to transmit data and need to be able to tell which specific connection failed or succeeded. There are NSURLDelegate methods (didFailWithError, etc) which return the related NSURLConnection. The problem is that there is no NSURLRequest returned in the delegate methods (and there is no NSURL accessor in the NSURLConnection).
The solution I've implemented is to maintain a NSMutableDictionary which pairs the URL string that was sent with the result of this NSURLConnection's "hash" method.
I've tested it and it seems to work - the hash of the NSURLConnection that is returned in the delegate method is the same as the hash from the NSURLConnection that was sent initially.
My question: is it safe to do this? Is there a better key to use than the hash? I'm asking because in my naive understanding, the hash is somehow associated with the address of that object in the memory, and it seems possible that backgrounding the app or turning the phone off and on may change this value as things are rewritten to memory.
Thanks very much!

I generally use ASIHTTPRequest, and when issuing multiple connections (concurrently in queue or parallel) I use the userInfo dictionary to pass around context.
The "hash IVAR" you refer to is actually defined in the NSObject protocol - as a method. It is intended to be used in a hash table, and as such should be sufficient for your needs.
I'd still prefer a more first-class approach to this problem, whilst making it more explicit which request is finishing/erroring-out.

Related

Architectural approach to HTTP communications and the parsing of returned JSON in iOS

Good evening guys,
My question is more of an engineering/design pattern approach than specifically technical.
I am developing an app that requires lots of interaction with a remote API returning JSON objects. The retrieval, parsing and utilisation of the data is not a problem and is working very smoothly. I am wanting to get some direction on the best design approach for this sort of scenario.
I will explain what I have so far (in pseudo code and declarations) and see if you can help:
A HTTP Fetcher class implementing the necessary NSURLConnection delegate methods. I initialise the class with the callback method selector like so for returning to the calling class on completion
#implementation HTTPFetcher{
- (id)initWithUrlRequest:(NSURLRequest *)aRequest receiver:(id)aReceiver action:(SEL)aReceiverAction
{
//set the member variables etc..
}
//all NSURLConnection delegate methods
- (void)connectionDidFinishLoading...
{
[receiver performSelector:action withObject:self];
}
}
I then have a Singleton HTTPController class for calling the HTTPFetcher:
- (void)postWithRequestString:(NSString *)aRequestString
{
[urlRequest setHTTPBody:[aRequestString dataUsingEncoding:NSUTF8StringEncoding]];
fetcher = [[HTTPFetcher alloc]initWithUrlRequest:urlRequest receiver:self action:#selector(receivedDataFromService:)];
[fetcher start];
}
- (void)receivedDataFromService:(HTTPFetcher *)aFetcher{
//handle the received data and split the parent object into an NSMutableDictionary
}
Now this approach works fantastically well for the app I have especially given the separate entities that I have to model (I will basically have a Singleton HTTPController for each entity).
My issue is where to handle the custom parsing of the JSON. Currently, I am doing the parsing the in ViewController where the data is required but this is too close to the source and needs to be abstracted out further but I am unsure how.
Should I include the methods to facilitate the parsing within the Singleton classes or should I create further controllers for parsing actions?
I look forward to hearing from you
Thanks
I would recommend you build on an existing JSON parsing library, in particular John Engelhart's JSONKit, considering it's arguably the highest performance JSON parsing library out there for iOS. Saves you implementing custom JSON parsing at all, but especially saves you implementing code which turns out to be too slow for your needs and then you will need to iteratively refine it until it gets fast enough for you to use.
For HTTP requests, I know you've implemented the behaviour already, but you might want to investigate ASIHTTPRequest or AFNetworking as general purpose networking libraries which have a reputation for being quite robust. Note AFNetworking uses the above JSONKit library for JSON parsing.
The way ASIHTTPRequest (the library I use in my projects) works is by using a delegate object implementing the protocol ASIHTTPRequestDelegate, which you assign after creating a request with a URL. There's a global network queue which is just an NSOperationQueue, and that handles asynchronous or multiple concurrent active requests.
You can setDelegate: for the object to start checking whether your delegate has implemented any of the methods at different points, such as didReceiveData: or requestDidFinish: by default, but you can also set a custom selector path to check by using the methods for individual operations (setDidFinishSelector:#selector(downloadComplete:)).
What you could do when, for example, the didReceiveData: callback happens, is pass the newly received data into a buffer stored in a wrapper class for an ASIJSONRequest (or use AFNetworking, which already encapsulates this). When the buffer is such that there is a complete JSON object in there which can be parsed correctly, then you call out to JSONKit to do the grunt work and then maybe send another callback yourself to an ASIJSONRequestDelegate for didReceiveData:, but now the data is in a format which is readable by the rest of your application.
Another method of using ASIHTTPRequest is with blocks. There is support for setting a completion block for a request, a block that is called when data is received, etc. For this design pattern you don't even need a wrapper class, just set the code block up to do the parsing itself and return any new data parsed to its desired destination.
One possibility would be for the View or view controller to ask a Model object for any state that it needs (including stuff from a remote server). The Model object would be told when there was any new data from the server, and it could then call any required data munging routines required to update its internal state (converting plists or json into a more canonical dictionary format, for instance).

ways to bind model classes in Objective-C

(I hope someone will correct my terminology if I get it wrong -- I'm still sorting out terms)
I have a series of classes in my model. I need to get some data from a url (SatDataGetter) and combine it with a location and date specific calculation (DayCalculater), do some further calculations (DataMixer), some interpretation to make it user-understandable (Advisor), and then present the results in a view.
There are issues with setting up the dependencies and making sure that, for instance, the SatDataGetter has valid data before it gets called by DataMixer, before it gets called by.. you get the idea. Of course, if the location changes, I need to update the whole thing from the bottom up. At minimum I have to get a message to the ViewController and the Advisor to reload their data.
The research I've done suggests that NSNotification is one way to go, but I could also try Key-Value Observing. I found some old posts (2009) on KVO, suggesting some possible problems and difficulties with debugging. http://www.mikeash.com/pyblog/key-value-observing-done-right.html
What's the preferred method? What are the issues I should be considering in deciding --
For instance:
The SatDataGetter essentially returns a single number. KVO seems like a reasonable way for DataMixer to keep track of what that value is, but I don't think I want all the parent classes to be doing KVO on the dependent variables.
When do you choose an NSNotification and when KVO?
The difference between NSNotifications and Key-Value Observation is largely one of coupling, but there are also performance implications.
Anyone can subscribe to your NSNotifications. All they need to know is the string/key that you notify under. They don't need to know anything about your classes/object-graph etc. So when you want to notify a world that doesn't know about the details of your class, NSNotification is the way to go. For instance, if you're vending a framework to other developers, it's probably better to notify by NSNotification than by exposing the internals of your framework to the degree that might be necessary to allow consumers to Key-Value Observe your objects.
In order to KVO observe an object you first have to be able to get a reference to it, which is not strictly true of NSNotifications (but usually happens to be true in my experience.) Secondly, you need to know enough about the implementation to know what to observe. With NSNotification the notifier need only publish a notification string/key. With KVO, you need to know the name of a property of the object. Sure, someone could publish static strings and tell you "you can KVO me for these properties" but that effectively becomes an API contract that may be harder to maintain going forward. (Say, for instance, you want to remove that property in a future version -- then you have to rig up other things to continue to send those notifications and provide values when people call valueForKey: -- in short, once you do that, you can never change that property.)
The other thing to remember with these various degrees of coupling is that with KVO, there can be an expectation that the observer knows about the details of your classes/objects. After all, they're registering a very specific interest in your object; they claim to know what that means -- how it works. Therefore you might expect them to be sensitive to the performance implications. With NSNotifications, the consumer can observe your notification knowing virtually nothing about you, and may not be aware of performance implications of how they act in response to the notification.
The drawback shared between the two approaches is that, absent extra work, they're both delivered synchronously. The notifying object is at the mercy of what the observer chooses to do (synchronously) when it receives the notification. The two mechanisms differ here in that for NSNotification it's quite easy for the notifying object to use performSelector:afterDelay: to cause the notification to be sent "asynchronously" (with respect to the call that spawns the notification) on the next pass of the run loop (see also NSNotificationQueue). This is not as readily possible with KVO. This difference alone may be crucial in certain situation.
Generally, I find that the loose coupling of NSNotification lends itself to events that are either large-granule (i.e. potentially represent a large group of changes) or relatively infrequent. KVO notifications are, by their very nature, fine-grained. You're explicitly observing a change of a single property (per registration) on a single object. This has the potential to blow up the number of registrations and the number of notifications. Every observation has a performance cost to it.
Another shared drawback to both of these is debuggability. I mentioned in a comment above that KVO can be a challenge to debug, and it shares that challenge with NSNotificationCenter as well.
The key difference between these two and the delegate pattern is that delegate relationships are typically 1:1 (one delegate.) (Sure, you could have an array of delegates, but that's pretty uncommon, and debatably an anti-pattern.) NSNotification and KVO are both inherently 1:N (many observers.)
In closing, I always like to say, "use the highest level of abstraction that will get the job done." If you only need a 1:1 relationship, use a delegate. For 1:N notifications, if an NSNotification will work -- in other words if the desired coupling is low and/or the notifications are large-grained or infrequent, use NSNotifications. If the coupling is tight, or the need is fine grained, use KVO. Also remember that you can adapt a delegate pattern from 1:1 to 1:N by having the delegate send NSNotifiations. With NSNotifications and KVO, you can't really control who observes you or how many observers you have.
I generally use KVO to watch for changes to properties within an object - so, instead of overriding the setter for an object, I'll use KVO to fire the observe method on a change, and then call other methods at that point.
I tend to use NSNotifications to inform other objects that something has happened. In your example, I may have a singleton to handle the location stuff, and then send a notification when userLocation changes.
And, of course, you can also use the delegate pattern to notify another object of a change.
These aren't hard and fast rules though...I'm wont to change on a whim!
You probably don't need any of those strategies, you can probably get by with some sort of delegate hierarchy. If you are using core location or any other service that you can't get reliable data from synchronously, then you can use that as your starting point... if you have 2 such services, (getting http data, and Core Location for instance), Then you may have to perform some caching and delegation... i.e. last best location + current http data get pushed to the view.
How about NSOperations?
// create two ops, and set a dependency
DownloadOp *op = [[Download alloc] initWithURL:#"http://xxx"];
CalculationOp *op = [CalculationOp new];
[calculationOp addDependency:downloadOp];
// ... more steps
// add to the queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:downloadOp];
[queue addOperation:calculationOp];
// runloop for unit testing
while(!parserOp.isFinished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
Inside the -[CalcuationOp start]:
// get the result from the previous step
id obj = [self.dependencies objectAtIndex:0];
if ([obj isKindOfClass:[DownloadOp class]]){
DownloadOp *op = (DownloadOp*) obj;
self.input = op.output;
}
Inside the AdvisorOp:
// update the GUI from the main thread
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue,^{
// update some UI element
});
Then listen to location updates on the CLLocationManager delegate to start the whole thing. I'm using this with the logic decoupled from the operations so I can unit test each part alone.
Benefit: it runs asynchronously and you can cancel the operations on the queue at any time. Downside: you have to learn NSOperation.

Does it make a difference in performance if I use self.fooBar instead of fooBar?

Note: I know exactly what a property is. This question is about performance.
Using self.fooBar for READ access seems a waste of time for me. Unnecessary Objective-C messaging is going on. The getters typically simply pass along the ivar, so as long as it's pretty sure there will be no reasonable getter method written, I think it's perfectly fine to bypass this heavy guy.
Objective-C messaging is about 20 times slower than direct calls. So if there is some high-performance-high-frequency code with hundreds of properties in use, maybe it does help a lot to avoid unnessessary objective-c messaging?
Or am I wasting my time thinking about this?
This kind of premature optimization should really be postponed until you actually notice or measure (with Instruments.app) a real problem.
No offence, but you're probably wasting your time thinking about it. Unless you have code that accesses that property thousands of times a second, then you're not going to see any performance differences.
The two aren't really interchangeable (ok some of the times they are). Access the ivar directly when that is what you need and use the accessor methods when that is what you need. It will probably depend on the the class hierarchy, the implementation of the class, is the code thread safe etc, etc.
All things that are largely upto you if it's your code. Might someone want to subclass this class and write a custom implementation of -foobar that always returned #"BOO" but they find that the superClass method -printFooBar now prints #"hello darling" because it prints out the value of the variable foobar instead of the value returned from self.foobar ?
Calling the accessor method does have more overhead than using the variable directly, but there are more things to consider than performance. Personally i find the position "always use the accessor method" just as ridiculous as saying "never use the accessor methods" - which would clearly be ridiculous.
Yes using property getters are much slower than direct access. A property getter is useful outside of the self class (and categories) for encapsulation, but I see no benefits using a self.ivar getter, unless you have overridden the getter to something else.
(And why are you using self.ivar in the first place?)
The only cases where self.ivar will be different from self->ivar are:
The property is atomic, so self.ivar will be similar to
spin_lock(&ivar_lock);
id retval = [ivar retain];
spin_unlock(&ivar_lock);
return [retval autorelease];
for an id property, and
spin_lock(&ivar_lock);
spin_lock(&destination_lock);
memcpy(&destination, &ivar, sizeof(ivar));
spin_unlock(&ivar_lock);
spin_unlock(&destination_lock);
for a struct. There is no difference between the two when the property is nonatomic.
When the class is not final. A category of the class or a subclass can override the property getter to something else. But I think overriding a concrete property is not a good style.
Like what the others have said, unless you have tested that the getter is a hot spot, changing it back to direct ivar access won't help much.
Some may disagree, but I happen to like accessing the ivar directly and bypassing the whole messaging business where possible. I think it makes my intentions clearer, since if I ever need to message the getter (for memory management or the like), then I will.
It's a tiny bit less efficient, but you still should generally not make your object state public. Although public members are considered bad in most OO languages, there's actually a pragmatic reason why in Objective-C: The framework uses your "getter" and "setter" methods to make certain things automatic, such as memory management and KVO notifications. With ivars accessed from multiple places, every piece of client code needs to fully understand all the responsibilities that the accessor methods were taking on and perform those duties in the exact same way itself.
So it's no "absolutely don't access your own ivars," but just make sure you fully understand what it entails in a given situation.

how to manage multiple asynchronous NSURLConnection delegates?

I have a class that makes multiple asynchronous connections where each connection performs its own logic in the delegate methods.
Because the delegate is the class itself, how can I implement this separation in logic in the NSURLConnection delegate methods?
My vote is for creating a different class for each operation you're doing. It may sound like a lot more work, but your code is going to be a heck of a lot cleaner which will probably lead to less bugs.
March 2014 edit - Don't use the delegate methods, use blocks.
Sounds to me like you need to better represent your objects in terms of object orientation.
You should have one class that manages multiple classes that each manage their own URL connection.
Either check the passed in NSURLConnection against a saved value to see which connection is responsible; or make the delegate different objects; or make the callback behave in a generic manner.
I ran into this problem like this. I have a class that does the same thing. I worked around it by storing each NSURLConnection object in a mutable dictionary instance var with its hash as the key. I then added a cancelAllConnections method in the class and I call it in each view controller's viewDidUnload method. The method removes all the connection objects in the mutable dictionary. Then I added a check in NSURLConnection's connectionDidFinishLoading to check for the hash key in the mutable dictionary. If the hash value doesn't exist, that means the connection was canceled, and the the callback selector won't be performed on a garbage object.

Accessing Instance Attributes from Secondary Thread (iPhone-SDK)

I have a class with an NSDictionary attribute. Inside this class I dispatch another thread to handle NSXMLParser handling. Inside my -didStartElement, I access the dictionary in the class (to compare an element found in the XML to one in the dictionary).
At this point I get undefined results. Using NSLog (I'm not advanced in XCode debugging), I see that it bombs around access of the NSDictionary. I tried just iterating the dictionary and dumping the key/values inside the didStartElement and this bombs at different keys each time.
The only thing I can conclude is that something is not kosher that I'm doing with regards to accessing main thread attributes from the secondary thread. I'm somewhat new to multithreading and am not sure what the best protocol is safely access attributes from additional threads.
Thanks all.
I would be surprised if you could access memory used by one thread in another thread unless that dictionary is static/global. I would take one of two approaches, not knowing the intricacies of the iPhone SDK -
Handle all of the dictionary access in the separate thread (population, instantiation, lookups, etc.)
Use some sort of iPhone equivalent of a thread-safe dictionary: link
There are few ways to enable thread-safe access to instances variables in Objective-C. The simplest way is to define your #property declaration as atomic. In this case the auto-generated setters and getters would be synchronized on self.
The other way is to wrap your critical code in a #synchronized block.
The most preferable way would be to create an NSOperation subclass that handles the fetching and parsing, and provides callbacks via delegation or blocks (if you're >= iOS4.0), to notify your consumer that the operation was completed.
Concurrent NSOperations require a bit of boilerplate code in order to get them working correctly, see this (the example is for Snow Leopard, but the concept is the same): http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/