Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何通过使用单个解析器的多个ViewController在解析端通知ViewController_Iphone_Objective C_Nsxmlparser - Fatal编程技术网

Iphone 如何通过使用单个解析器的多个ViewController在解析端通知ViewController

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的委托方法:

我创建了一个RSS解析器和3个TableView,它可以很好地解析RSS文件,但我不知道如何在解析结束时通知TableViewController,以便它可以更新视图。 TableViewController启动解析器并解析提要

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时。啊,好的,那么您需要委托模式:)我会将其添加到我的答案中。谢谢,伙计,我感谢您的帮助。谢谢这个例子,让我了解了如何充分使用它。