Iphone 如何通过使用单个解析器的多个ViewController在解析端通知ViewController
我创建了一个RSS解析器和3个TableView,它可以很好地解析RSS文件,但我不知道如何在解析结束时通知TableViewController,以便它可以更新视图。 TableViewController启动解析器并解析提要Iphone 如何通过使用单个解析器的多个ViewController在解析端通知ViewController,iphone,objective-c,nsxmlparser,Iphone,Objective C,Nsxmlparser,我创建了一个RSS解析器和3个TableView,它可以很好地解析RSS文件,但我不知道如何在解析结束时通知TableViewController,以便它可以更新视图。 TableViewController启动解析器并解析提要 parser = [[RSSParser alloc] initWithURL:@"http://randomfeed.com"]; 我可以访问单个提要项,如 [parser feedItems]; 在parser.m中,我实现了NSXMLParser的委托方法:
parser = [[RSSParser alloc] initWithURL:@"http://randomfeed.com"];
我可以访问单个提要项,如
[parser feedItems];
在parser.m中,我实现了NSXMLParser的委托方法:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
- (void)parserDidEndDocument:(NSXMLParser *)parser
@implementation XMLParser
@synthesize delegate;
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.delegate parserDidFinish:dataYouCollectedArray]; //this is where it happens.
}
那么,如何让parserDidEndDocument通知我的控制器,以便将数据添加到tableview中呢
来自obj-c初学者的欢呼声。如果您需要多个对象收到单个事件的通知,那么委托方法通常会开始变得混乱 通知是一个很好的选择
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kInternetAvailableNotification object: nil];
上面为当前对象添加了一个“侦听器”,用于侦听任何触发
kInternetAvailableNotification。当事件发生时,调用方法“reachabilityChanged”
在dealloc方法中,请记住注销通知:
- (void)dealloc {
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:kInternetAvailableNotification
object:nil];
[super dealloc];
}
现在,您可以在代码中的任何位置向侦听器通知某个事件:
[[NSNotificationCenter defaultCenter]
postNotificationName:kInternetAvailableNotification
object:nil];
NSNotifications可以发送带有
听众可以使用
因此,每个需要知道新数据何时可用的控制器都可以为
kInternetAvailableNotification通知(它只是由NSString定义的名称)
并被告知
这是一个简短的介绍:)好的,委托模式在Cocoa框架中被广泛使用 解析数据的文件必须有一个协议,任何想要回调的人都可以使用这个协议 类必须实现协议中的方法:
//XMLParser.h
//import statements here ..
@protocol XMLParserDelegate
- (void) parserDidFinish:(NSArray*) theParsedData; //have as many methods as you please, didFail, doingProgress etc.
@end
@interface XMLParser : NSObject {
id <XMLParserDelegate> delegate; //we don't know what type of object this will be, only that it will adhere to the XMLParserDelegate protocol.
}
@property(assign) id delegate;
//methods
@end
因此,在控制器接口文件中,您表示将遵守XMLParserDelegate协议
//MyController.h
#import "XMLParser.h"
@interface MyController : UIViewController <XMLParserDelegate> { //this is where you "promise" to implement the methods of the protocol.
}
这是一个很好的模式,它将调用方和响应方松散地耦合在一起,而不让他们知道协议规定的其他任何内容
如果我有一个视图元素,它只限于自己的功能,比如说时钟。
我会有一个ClockViewController,它会实例化arm、拨号等。它们都会链接到时钟,并使用此模式提醒时钟控制器它们的操作。这样,只要实例化它们的对象遵循ClockArmDelegate协议,我就可以随意使用时钟臂或拨入其他代码
//MyController.h
#import "XMLParser.h"
@interface MyController : UIViewController <XMLParserDelegate> { //this is where you "promise" to implement the methods of the protocol.
}
希望它有意义:)我很确定,这是可可中使用最多的模式。我在这里看到三种可能的解决方案:
- NSNotifications。易于实现,但并不总是具有良好的可维护性(您永远不知道哪个对象已注册到您的通知中)
- 委托数组(而不是单个委托),并在数组的每个对象上调用委托方法。Three20经常使用这种模式(Three20是一个很好的参考),但它看起来仍然像是委托模式被拉伸得太远了
- 在数据对象上观察键值。例如,如果您的模型上有一个属性“RSSItems”,其中包含已解析的RSS数据,则可以注册每个控制器以侦听对RSSItems对象的更改:
[rssParser addObserver:yourViewController forKeyPath:@"RSSItems" options:NSKeyValueObservingOptionNew context:NULL];
解析器:didEndElement:
方法中,设置RSSItem的内容,从而触发KVO通知
我认为第三种选择是最好的:它是一种标准的Cocoa机制,不需要系统范围的通知,也不会将委托模式延伸太远。对不起,我的错误是,应该只通知控制器自己的RSSParser实例。加载项:我想以某种方式运行[mytableview reloadData]当调用parserDidEndDocument时。啊,好的,那么您需要委托模式:)我会将其添加到我的答案中。谢谢,伙计,我感谢您的帮助。谢谢这个例子,让我了解了如何充分使用它。