Multiple Methods NSNotificationCenter iPhone - iphone

I have many methods that need the previous one to complete before firing the next one. I'm thinking I should NSNotificationCenter rather than performSelector afterDelay and just hope the method is done by that time.
Can someone map out how and where to add the notification to Method1, Method2 and Method3 where 1 needs to complete (not just fire) before 2 before 3.
Thanks

In general do not use notifications as method calls. They should be used to indicate that something did or will occur.
From Apple's "Coding Guidelines for Cocoa":
Notifications are identified by global NSString objects whose names are composed in this way:
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
For example:
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification

Related

Can someone tell me the difference between the call in IOS

I have a method called Display. Can somebody explain me the difference of calling the same method in the following two ways.
[self Display];
[self performselector:#selector(Display)]
- (void)Display {
NSlog(#"Data");
}
both are basically the same with one minute difference.. #selector gives a name to your method which you can pass around as an attribute to other objects or in other function calls.
Like if you want to send a message to other object and you want to send display as an attribute then you will have to give it a name using #selector and thus you can send it.. its a pretty vague concept.. hope this helps.
and to quote apple documents...
"However, the performSelector: method allows you to send messages that
aren’t determined until runtime. A variable selector can be passed as
the argument:
SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector:myMethod];
The aSelector argument should identify a method that takes no
arguments. For methods that return anything other than an object, use
NSInvocation."
[self Display] is shorter and easier to read, write and comprehend.
[self performSelector:#selector(Display)] makes it possible to execute arbitrary selectors. If you save the selector in a variable, then you can execute it later on without knowing the method you invoke. It is therefore more flexible. Even better: you can pass selectors and objects to other objects and let them invoke it for you when necessary. An example why you want to use this is the NSUndoManager which simple invokes a selector to undo an action if the user executes the Undo command.
I do not think that there is a big difference between examples you provided, but perform selector is very useful when you for instance wanna move execution of your method to the background thread.
[self Display]; is a call to a known method on a known object.
It's easy to give it some params if your want : [self DisplayWithParam1:(NSString*)aString param2:(int)aNumber param3:(NSDictionary*)aDict
[self performselector:#selector(Display)] is a call that allows you to call a possibly not known method on a possibly not known object type.
Let's imagine you have many kind of classes that all respond to a given protocol that require to have the Display method implemented. You put some objects of thoses different classes in an NSMutableArray. When parsing the array later, you will get id typed objects.
So calling[myArrayObject Display]; will work at runtime but will generate a warning at compile time as id does not support any method of course, even if you know that this object supports the method.
To prevent thoses warning, call [myArrayObject performselector:#selector(Display)];.
The problem with that call is that is harder to pass some parameters.
performSelector:withObject:withObject:
Sends a message to the receiver with two objects as arguments.
- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject
Parameters
aSelector
A selector identifying the message to send. If aSelector is NULL, an NSInvalidArgumentException is raised.
anObject
An object that is the first argument of the message.
anotherObject
An object that is the second argument of the message
Return Value
An object that is the result of the message.
Discussion
This method is the same as performSelector: except that you can supply two arguments for aSelector. aSelector should identify a method that can take two arguments of type id. For methods with other argument types and return values, use NSInvocation.
Availability
Available in Mac OS X v10.0 and later.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html
The #select call is faster. Generally the uglier (and less dynamic) the code you have in Objective-C, the faster it runs. Here, the selector call bypasses the usual call to objc_msgSend().
I wouldn't recommend writing code like this if you can avoid it. Selectors are somewhat common in Cocoa, but if you're using it for a speedup it's really not worth it. objc_msgSend() is highly optimized and very fast.

Use of NSSet to hold a list of delegates in Objective C

I am writing a component (e.g. VeryLongJobExecuter) in Objective C.
I want this VeryLongJobExecuter to be able to notify other objects (one to many) when its job is finished, and execute a common method, e.g. (jobExecuted).
I am thinking to store the reference of these delegates in either NSArray/NSSet, and iterate the delegates and call the method.
Or should I use Notification instead?
The reason that we have notifications is so that you don't have to keep a reference to every other object that might care about an event. Don't re-invent the wheel.
Notification was done for that purpose so I would use that instead.

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.

Subclassing NSCalendar?

I'm trying to make a subclass of NSCalendar, but without much luck. I've tried two ways:
thorough categories. I can create a modified object and a test method that I added (not part of NSCalendar) works just fine, but overriden methods don't work - e.g. if I call dateFromComponents:, the NSCalendar method is apparently called, not what I wrote in the category definition
regular subclass. In this case I can't even create an instance: initWithCalendarIdentifier throws a _CFRequireConcreteImplementation exception. Initially I only had a couple of methods overriden in the subclass, but then I've overriden all of the (documented) NSCalendar methods - and the result is the same.
Is it even possible to subclass NSCalendar?
The reason I want to do it is to make repeating Local Notifications with non-standard repeat intervals. The default functionality allows Local Notifications to repeat every [calendar unit], but I need irregular intervals - e.g. I can emulate "every 15 minutes" notifications by creating 4 "every hour" notifications 15 minutes apart, but I need them to fire at, say T+20, T+22, T+24, T+44, T+46, T+66 minutes and so on (T is the start time) - the interval between notifications is 20 minutes, then 2 minutes, then 20 minutes again and so on.
I was hoping that, since UILocalNotification wants an NSCalendar (in repeatCalendar property) to calculate when to fire the next notification, I can achieve what I want by overriding, say, dateFromComponents to just return [NSDate dateWithIntervalSinceNow] with interval alternating between 20 and 2 minutes - but my cunning plan seems to have a major problem because of the inability to subclass NSCalendar.
Edit: This whole thing is needed for when the app is in the background. In the foreground I use timers, just like No one in particular suggests.
Even if you do manage to subclass NSCalendar, I doubt it'll work. I strongly suspect that local notifications are scheduled by SpringBoard, and I don't think it's going to launch/resume your app every time it needs to see what the next fire date is.
The first step is to find out what UILocalNotification is doing with your calendar. The easiest way to do this is to write an NSObject subclass which forwards undefined method calls and prints log messages (respondsToSelector:, methodSignatureForSelector:, forwardInvocation:). Generally, you want something like if ([super respondsToSelector:selector]) { return [super ...]; } else { return [target ...]; }.
Then, the easiest hack is to write a class which implements the necessary methods of NSCalendar for your purposes.
You might also consider calling [super init]; -[NSCalendar initWithCalendarIdentifier:] is likely to return a different self (e.g. [self release]; return [[NSGregorianCalendar alloc] init]), and you don't want that. What calendar identifier are you passing it? Maybe it's complaining that it requires a "concrete implementation" that it knows about for the calendar identifier you're passing.
A direct inherit from NSCalendar is tricky because I think that it's a class cluster. I'm a bit fuzzy on this concept so I'll give you a link to the Apple document instead of making a greater fool of myself.
http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW34
Try using the NSTimer method
+ (NSTimer *)scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
Set the repeats to TRUE and have a time interval of 2 minutes. Have a counter that you set to 1 or 10. Everytime the selector is called you decrement the counter until it reaches 0 when you do your work and reset the counter.

Dealing with variable assignments and async requests

I'm looking for a reliable design for handling assignments that have asynchronous requests involved. To further clarify, I have a class which handles Data Management. It is a singleton and contains a lot of top level data for me which is used throughout my iPhone application.
A view controller might do something such as the following:
users = [MySingleton sharedInstance].users;
MySingleton will then override the synthesized users getter and see if it is set. If it is not set, it will speak to a Connection Manager (a wrapper for NSURLConnection and its delegate methods) which fires off an asynchronous request, and this is where problems begin. I cannot guarantee when "users" will be available. I could change the request to synchronous, but that will directly effect user experience, especially in a mobile environment where bandwidth is limited already.
I need to be able to at some point, have some kind of locking/synchronization code going on in my getter that doesn't return users until it is available or is nil.
Once the NSURLConnection has the data available, it needs to callback something/somewhere with a response object and let the getter know the data is available.. whether it's failed or succeeded.
Any suggestions on handling this?
I solved this problem a couple ways in different apps.
One solution is to pass an object and selector along to notify such as:
- (id)getUsersAndNotifyObject:(id)object selector:(SEL)selector
This breaks the nice property behavior however. If you want to keep the methods as properties, have them return immediately, with either cached data or nil. If you need to go out to the network, do so asynchronous and then let the rest of the app know the data changed via KVO or the NSNotificationCenter. (Cocoa Bindings would be an option on the Mac, but they don't exist on iPhone).
The two methods are fairly similar. Register for updates with your shared instance, and then ask for the data. KVO is a little lighter weight if you just dealing with raw observable properties, but an NSNotification might be more convenient if you're interested in several different pieces of data.
With an NSNotification, the client object could register for one type of notification which includes the changed data in its userInfo dictionary instead of having to register obvservers for every single key path you're interested in.
An NSNotification would also allow you to pass back failures or other status information a lot more easily than straight KVO.
KVO method:
// register observer first so you don't miss an update
[[MySingleton sharedInstance] addObserver:self
forKeyPath:#"users"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:&kvo_users_context];
users = [MySingleton sharedInstance].users;
// implement appropriate observeValueForKeyPath:ofObject:change:context: method
NSNotification Method:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(sharedDataChanged:)
name:MySingletonDataUpdatedNotification
object:[MySingletonDataUpdatedNotification sharedInstance]];
users = [MySingleton sharedInstance].users;
// implement appropriate sharedDataChanged: method
You can either use a delegate pattern or a notification pattern here.
A delegate would let a particular object know when users is complete, a notification pattern would notify any object that wants to know. Both are valid, depending on your situation.
Just remember: if you have any race issues in your app, your architecture is probably all wrong.
It took me a while to realize what the best way of handling this kind of typical task; it turns out the clue is in the design of many of Cocoa and CocoaTouch's own APIs: delegation.
The reason so many of Cocoa's APIs use delegation is because it fits very well with the asynchronous nature of many GUI apps.
It seems perfectly normal to want do do something along the lines of:
users = [MyDataFactory getUsers];
Except, as you point out, you have no idea when the getUsers method will finish. Now, there are some light-weight solutions to this; amrox mentioned a few in his post above (personally I'd say notifications aren't such a good fit but the object:selector: pattern is reasonable), but if you are doing this kind of thing a lot the delegation pattern tends to yield a more elegant solution.
I'll try to explain by way of an example of how I do things in my application.
Let's say we have a domain class, Recipe. Recipes are fetched from a web service. I typically have a series of repository classes, one for each entity in my model. A repository class' responsibility is to fetch the data required for the entity (or a collection of them), use that data to construct the objects, and then pass those objects onto something else to make use of them (typically a controller or data source).
My RecipeRepository interface might look something like this:
#interface RecipeRepository {}
- (void)initWithDelegate:(id)aDelegate;
- (void)findAllRecipes;
- (void)findRecipeById:(NSUInteger)anId;
#end
I'd then define a protocol for my delegate; now, this can be done as an informal or formal protocol, there are pros and cons of each approach that aren't relevant to this answer. I'll go with a formal approach:
#protocol RepositoryDelegateProtocol
- (void)repository:(id)repository didRetrieveEntityCollection:(NSArray *)collection;
- (void)repository:(id)repository didRetrieveEntity:(id)entity;
#end
You'll notice I've gone for a generic approach; you will likely have multiple XXXRepository classes in your app and each will use the same protocol (you may also choose to extract a base EntityRepository class that encapsulates some common logic).
Now, to use this in a controller, for example, where you previous would have done something such as:
- (void)viewDidLoad
{
self.users = [MySingleton getUsers];
[self.view setNeedsDisplay];
}
You would do something like this:
- (void)viewDidLoad
{
if(self.repository == nil) { // just some simple lazy loading, we only need one repository instance
self.repository = [[[RecipeRepository alloc] initWithDelegate:self] autorelease];
}
[self.repository findAllRecipes];
}
- (void)repository:(id)repository didRetrieveEntityCollection:(NSArray *)collection;
{
self.users = collection;
[self.view setNeedsDisplay];
}
You could even extend this further to display some kind of "loading" notice with an additional delegate method:
#protocol RepositoryDelegateProtocol
- (void)repositoryWillLoadEntities:(id)repository;
#end
// in your controller
- (void)repositoryWillLoadEntities:(id)repository;
{
[self showLoadingView]; // etc.
}
Another thing about this design is that your repository classes really don't need to be singletons - they can be instantiated wherever you need them. They may deal with some kind of singleton connection manager but at this layer of abstraction a singleton is unnecessary (and its always good to avoid singletons where possible).
There is a downside to this approach; you may find you need layers of delegation at each level. For instance, your repositories may interact with some kind of connection object which does the actual asynchronous data loading; the repository might interact with the connection object using it's own delegation protocol.
As a result you might find you have to "bubble up" these delegation events throughout the different layers of your application using delegates that get more and more coarse-grained as they get closer to your application-level code. This can create a layer of indirection that can make your code harder to follow.
Anyway, this is my first answer on SO, I hope its been helpful.