Создание простого класса утилит - PullRequest
1 голос
/ 03 мая 2011

Я хочу создать класс, чтобы ускорить такие вещи, как получение делегата приложения, анализ xml

Реализация утилит как функции класса, кажется, имеет смысл.В конце концов, это всего лишь функция, которую мы можем вызвать глобально.

Но потом, когда я выполняю

[xmlParser setDelegate:self];

, у меня проблемы.В функции класса self ссылается на класс.

Каким было бы элегантное решение для этого, если вы программист target-c

Если я включу (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 Ответ

1 голос
/ 03 мая 2011

Есть несколько способов решить ваши проблемы с помощью BNUtilitiesQuick.

Основная причина, по которой у вас возникают проблемы, заключается в том, что NSXMLParser использует механизм обратного вызова.Это сделано для того, чтобы вам не приходилось читать весь документ в память сразу - он анализируется по ходу дела.Это означает, что вам нужен уникальный объект делегата для каждого NSXMLParser, который вы создаете.

Решение № 1 - используйте шаблон Singleton

BNUtilitiesQuick может быть singleton , но тогда вывозникнут проблемы, если вы вызовете его дважды из двух разных потоков (класс будет получать сообщения из обоих документов XML, которые анализируются одновременно).Если многопоточность не является проблемой, это будет работать.

Решение №2. Переключение синтаксических анализаторов XML (избегайте проблемы)

Другое решение заключается в использовании другого синтаксического анализатора XML, который не требует подхода синтаксического анализа на основе делегатов.NSXMLParser основан на SAX, который обычно использует шаблон обратного вызова или делегата.Рэй Вендерлих имеет отличный пост в своем блоге о различных синтаксических анализаторах XML, доступных в iOS, и о том, как выбрать ваш любимый.

Решение № 3 - Создайте объект делегата в методе

Добавьте еще один уровень абстракции - ваш метод синтаксического анализа XML должен создать новый экземпляр нового класса XML Parser Delegate, который будет обрабатывать обратные вызовы для этой конкретной операции синтаксического анализа.Затем, когда вы создаете синтаксический анализатор, присвойте делегату этот вновь созданный объект и проанализируйте XML.

В вашем классе Utils не сохраняется состояние, поэтому вам не нужно беспокоиться о многопоточных проблемах..

Может также помочь вернуть проанализированный объект вместо (void) в вашем методе синтаксического анализа - это похоже на еще одну ловушку вашего проекта.

...