Создание простого класса утилит

#objective-c #nsxmlparser

#objective-c #nsxmlparser

Вопрос:

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

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

Но затем, когда я делаю

 [xmlParser setDelegate:self];
  

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

Каким было бы элегантное решение для этого, если вы программист objective-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:

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

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

Решение № 1 — использовать одноэлементный шаблон

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

Решение № 2 — Переключить анализаторы XML (избежать проблемы)

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

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

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

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

Также может помочь возврат анализируемого объекта вместо (void) в вашем методе parse — это кажется еще одной ошибкой вашего дизайна.

Комментарии:

1. Мне нравится третье решение. Таким образом, будет 2 версии BNUtilitiesQuick для экземпляра и для класса. ОЧЕНЬ ХОРОШО.

2. Функция синтаксического анализа записывает данные в coredata.