创建一个简单的实用程序类

时间:2011-05-03 18:22:33

标签: objective-c nsxmlparser

我想创建一个类来加速诸如获取应用程序委托,解析xml

之类的事情

将utilites实现为类函数似乎有意义。毕竟它实际上只是一个我们可以全局调用的函数。

但是当我做的时候

[xmlParser setDelegate:self];

我遇到了麻烦。在类函数中,self指向类。

如果你是一个客观的程序员,那么优雅的解决方案是什么

如果我将(void)parseXMLFileAtURL:(NSString *)URL转换为实例变量,那么事情看起来就不对了。 BNUtilitiesQuick甚至没有字段,我真的打算在任何地方都可以访问。

如果我把BNUtilitiesQuick作为NSObject的类别,这看起来很尴尬。为什么我的程序中的所有类都可以成为XMLParser的委托

那我该怎么办?

@implementation BNUtilitiesQuick


+ (BadgerNewAppDelegate *)appDelegate
{

    return [[UIApplication sharedApplication] delegate];
}

+ (NSManagedObjectContext*)managedObjectContext;{
    return [[BNUtilitiesQuick appDelegate] managedObjectContext];
}



+ (void)parseXMLFileAtURL:(NSString *)URL {


    //you must then convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    // here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
    // this may be necessary only for the toolchain
    NSXMLParser* xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:xmlURL] autorelease];

    // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
    [xmlParser setDelegate:self];

    // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
    [xmlParser setShouldProcessNamespaces:NO];
    [xmlParser setShouldReportNamespacePrefixes:NO];
    [xmlParser setShouldResolveExternalEntities:NO];

    [xmlParser parse];
}

@end

1 个答案:

答案 0 :(得分:1)

有几种方法可以通过BNUtilitiesQuick来解决您的问题。

您遇到问题的主要原因是NSXMLParser使用回调机制。这样做是为了让您不必立即将整个文档读入内存 - 它会随着解析而解析。这意味着您需要为您创建的每个NSXMLParser创建一个唯一的委托对象。

解决方案#1 - 使用单例模式

BNUtilitiesQuick可能是singleton,但如果从两个不同的线程调用它两次,则会遇到问题(该类将从同时解析的两个XML文档中获取消息)。如果线程不是问题,这将起作用。

解决方案#2 - 切换XML解析器(避免问题)

另一种解决方案是使用不需要基于委托的解析方法的不同XML解析器。 NSXMLParser是基于SAX的,通常使用回调或委托模式。 Ray Wenderlich对于iOS上可用的不同XML解析器以及如何选择自己喜欢的解析器有一个很棒的post on his blog

解决方案#3 - 在方法

中创建委托对象

添加另一个抽象层 - 您的解析XML方法应该创建一个新的XML Parser Delegate类的新实例,该类将处理此特定解析操作的回调。然后,在创建解析器时,将委托设置为此新创建的对象,并解析XML。

您的Utils类中没有存储任何状态,因此您不必担心多线程问题。

在您的解析方法中返回解析的对象而不是(void)也可能有帮助 - 这似乎是您设计的另一个陷阱。