开发者

Objective-C Delegates: Have another class I call that parses XML. Need to know when its done externally

I have a class tha开发者_JAVA百科t calls another class to parse (NSXMLParse) from a URL. Now I would like for the class calling this one to know when it has finished, so that I can populate the UI. I am guessing a delegate would be the way to go but ive never worked with one and would need some guidance as to how this would be wired.

Thanks


NSNotification is, in my opinion, the easiest way to setup something like this.

This is a small snippet from one of my apps:

in method.m when the something I'm processing has finished

[[NSNotificationCenter defaultCenter] postNotificationName:@"GlobalTagsReady" object:nil];

in the class to take care of the notification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTags) name:@"GlobalTagsReady" object:nil];

where @selector(getTags) is the method to be called


Basically, delegation just means giving an object a pointer back to something that it needs to tell about what it's doing. In Cocoa, this is usually handled through “protocols”, which are sort of the reverse of an interface declaration: they describe what methods an object will call on another object that “implements” the protocol. They're not, strictly speaking, necessary, particularly in a simple situation like this, but they're good practice and a good thing to know if you're going to be writing modular code.

In the parsing class's header:

 // This is the protocol declaration; anything implementing the "ParsingDelegate" protocol needs to have any method signatures listed herein
 @protocol ParsingDelegate
 - (void)parsingDidEndWithResult:(NSDictionary *)result
 @end

 @interface ParsingClass : NSObjectOrWhatever
 {
      ...
      id<ParsingDelegate> _delegate;
 }
 ...
 // We'll use this property to tell this object where to send its messages
 @property(nonatomic,assign) id<ParsingDelegate> delegate;
 @end

In the parser's implementation:

 @implementation ParsingClass
 @synthesize delegate=_delegate;
 // the "=_delegate" bit isn't necessary if you've named the instance variable without the underscore
 ...

In the method in which the parser finishes its stuff:

 ...
 // make sure the delegate object responds to it
 // assigning an object that doesn't conform to the delegate is a warning, not an error,
 // but it'll throw a runtime exception if you call the method
 if(self.delegate && [self.delegate respondsToSelector:@selector(parsingDidEndWithResult:)])
 {
      [self.delegate performSelector:@selector(parsingDidEndWithResult:) withObject:someResultObject];
 }
 ...

In the UI class's header:

 @interface SomeUIClass : NSObjectOrWhatever <ParsingDelegate>

In the UI class, wherever it sets up the parser,

 parser.delegate = self;

then just implement the -parsingDidEndWithResult: method on the UI class. If you have multiple parsers running at once, you might want to extend the delegate method to pass in the parser object itself—that's kind of the Cocoa standard—but for the case you've described, this should do the trick.


You mainly got 3 ways to talk in cocoa: delegates, notifications and KVO. (cf http://alexvollmer.com/index.php/2009/06/24/cocoas-ways-of-talking/)

I assume that you are fetching the data and parsing the XML in a background thread. So whatever solution you are going to use, keep in mind to update the UI in the mainthread (using performSelectorOnMainThread for instance)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜