[iOS] Using Multiple Delegates

此份文件為個人學習事件驅動XML程式的翻譯,內文請參考蘋果官方文件,若有翻譯錯誤請見諒,請勿挪作商業用途,並著明出處。


對某些XML文件而言,特別是又大又複雜的文件,對於NSXMLParser物件提供單一委任可能不是最好的辦法。處理所有不同的解析事件的程式碼很容易變的過於複雜難懂而且難於管理。有一個可以讓我們更便於管理的技巧是讓多個委任共享處理解析事件的工作。

假設有個應用程式會將他遇到的元素建構一個DOM-style樹。從根元素開始,一個元素創建一個子元素並且把它設定成委任來把控制權交給它。那個子元素創見它的子元素們(如此繼續下去),每一次都會適當的重設委任。若某個元素沒有子元素,或它是一個混合的元素,它自己會累積文本內容。最後,當parser遇到一個元素的結束標籤,這元素會將委任設定為它自己的父元素。表一顯示了完成這樣過程的相關的程式碼。

表一:重設下一個元素的委任

- (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;
}


管理多個委任的另一個技巧是在collection(像是NSDictionary)中維持許多委任物件,每個物件都有特定扮演的角色。這些物件知道在任何情況下誰是他們的子元素和父元素,所以也能夠在目前的元素完成後為下一個元素設定委任(譯按:這段話的意思是,當解析完一個元素後,就要處理下一個元素了,所以就把解析的任務指定給專門用來解析這個元素的委任)。

留言