Используя многократных делегатов

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

Возьмите в качестве примера приложение, создающее дерево СТИЛЯ DOM из элементов, поскольку это встречается с ними. Запускаясь с корневого элемента, один элемент создает дочерний элемент и выдает управление к нему путем установки его, чтобы быть делегатом. Тот дочерний элемент создает свои дочерние элементы (и т.д.), каждый раз сбрасывая делегата соответственно. Если элемент не имеет никаких дочерних элементов, или если это - смешанный элемент, это накапливает текстовое содержание для себя. Наконец, когда синтаксический анализатор встречается с конечным тэгом элемента, элемент устанавливает делегата, чтобы быть его родительским элементом. Перечисление 1 показывает подходящий код, выполняющий эту обработку.

Перечисление 1  , Сбрасывающее делегата к следующему элементу

- (void)parser:(NSXMLParser *)parser
        didStartElement:(NSString *)elementName
        namespaceURI:(NSString *)namespaceURI
        qualifiedName:(NSString *)qualifiedName
        attributes:(NSDictionary *)attributeDict {
    // Element is a custom class for object representing element nodes
    // Creation of element sets child as delegate (see below)
    [self addChild:[Element elementWithName:elementName
        attributes:attributeDict parent:self children:nil parser:parser]];
}
 
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [self appendString:string];
}
 
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    Element *parent = [self parent];
    [parser setDelegate:parent]; // RESET DELEGATE TO PARENT
}
 
+ (id)elementWithName:(NSString *)elementName attributes:(NSDictionary *)attributes parent:(Element *)parent children:(NSArray *)children parser:(NSXMLParser *)parser {
    return [[[[self class] alloc] initWithName:elementName
        attributes:attributes parent:parent children:children
        parser:parser] autorelease];
}
 
- (id)initWithName:(NSString *)elementName attributes:(NSDictionary *)attributes parent:(id)parent children:(NSArray *)children parser:(NSXMLParser *)parser {
    self = [super init];
    if (self) {
         [self setName:elementName];
         if (attributes) {
               [self addAttributes:attributes];
         }
         [self setParent:parent];
         if (children) {
              [self addChildren:children];
         }
         [parser setDelegate:self]; // CHILD SET AS DELEGATE
    }
    return self;
}

Другой метод для управления многократными делегатами поддерживает много объектов делегата, каждого с его специализированной ролью, в наборе, таких как объект NSDictionary. Эти объекты знали бы, кто их дочерние и родительские элементы находятся в любом данном контексте и так были бы в состоянии установить делегата к следующему элементу (использующий надлежащий ключ словаря) после того, как закончилась их работа с элементом тока.