2015-09-18 2 views
1

Итак, я только что обновил свой swift до 2.0 и, очевидно, в моем коде появилось несколько ошибок. То, что у меня есть сейчас.Ошибка alloc() в swift

unc loadRssFeed(data: NSURL) { 

    var myRssParser : ParserManager = ParserManager.alloc().initWithURL(data) as! ParserManager 

    myRssFeed = myRssParser.feeds 

    tableView.reloadData() 
} 

Fixit предлагает изменить 'var' на 'let' и использовать инициализатор объекта вместо alloc(). Но проблема в том, что я никогда не использовал ее раньше (при условии, что мой опыт Swift похож на четыре недели).

Должен ли я следовать инструкциям fixit? И как исправить проблему alloc().

Спасибо!

Обновленный код остроумие парсер:

class ParserManager: NSObject, NSXMLParserDelegate { 

var parser = NSXMLParser() 
var feeds = NSMutableArray() 
var elements = NSMutableDictionary() 
var element = NSString() 
var ftitle = NSMutableString() 
var link = NSMutableString() 
var fdescription = NSMutableString() 
var fdate = NSMutableString() 


func initWithURL(url :NSURL) -> AnyObject { 
    startParse(url) 
    return self 
} 
func startParse(url :NSURL) { 
    feeds = [] 
    parser = NSXMLParser(contentsOfURL: url)! 
    parser.delegate = self 
    parser.shouldProcessNamespaces = false 
    parser.shouldReportNamespacePrefixes = false 
    parser.shouldResolveExternalEntities = false 
    parser.parse() 
} 

func allFeeds() -> NSMutableArray { 
    return feeds 
} 
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { 

    self.element = elementName 

    if self.element == "item" { 

     self.ftitle = "" 
     self.fdescription = "" 

     self.fdate = "" 

    } 
} 
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { 

    if (elementName as NSString).isEqualToString("item") { 
     if ftitle != "" { 
      elements.setObject(ftitle, forKey: "title") 
     } 



     if fdescription != "" { 
      elements.setObject(fdescription, forKey: "description") 
     } 

     if fdate != "" { 
      elements.setObject(fdate, forKey: "pubDate") 
     } 

     feeds.addObject(elements) 
    } 

} 
func parser(parser: NSXMLParser, foundCharacters string: String?) { 

    if element.isEqualToString("title") { 
     ftitle.appendString(string!) 

    }else if element.isEqualToString("description") { 
     fdescription.appendString(string!) 
    }else if element.isEqualToString("pubDate") { 
     fdate.appendString(string!) 
    } 
} 


} 
+0

Это должно быть просто 'пусть парсер = ParserManager (URL: данные) '. Не называйте 'alloc' и' init' следующим образом. – Rob

+0

Теперь он говорит, что в вызове есть дополнительный аргумент «URL». Будет ли это помогать, если я добавлю свой код парсера в мой оригинальный пост? –

+0

Это 'initWithURL' В классе' ParserManager' должен быть 'init' метод с параметром' URL'. – Rob

ответ

1

Как обсуждалось выше, вы не должны звонить напрямую alloc и init.... Кроме того, класс ParserManager не должен иметь метод initWithURL, а скорее метод init с параметром URL. Существующий код, как представляется, следует за шаблонами Objective-C, но Swift имеет свои собственные соглашения.

Но в более широком смысле я бы посоветовал не выполнять синхронные сетевые запросы, а когда вы звоните NSXMLParser(contentsOfURL:), это то, что происходит. Лучше запрашивать данные асинхронно, а затем реорганизовать код для следования асинхронным шаблонам (например, completionHandler закрытия). Например:

class ParserManager: NSObject, NSXMLParserDelegate { 

    /// The NSMutableArray used internally by this class 

    private var feeds = NSMutableArray() 

    /// Initiate parsing asynchronously; note, I'm returning the `NSURLSessionTask` in case you want to cancel it at some later point 

    func parse(URL: NSURL, completionHandler: (NSMutableArray?, NSError?)->()) -> NSURLSessionTask { 
     let task = NSURLSession.sharedSession().dataTaskWithURL(URL) { data, response, error in 
      guard data != nil else { 
       dispatch_async(dispatch_get_main_queue()) { 
        completionHandler(nil, error) 
       } 
       return 
      } 

      let parser = NSXMLParser(data: data!) 
      parser.delegate = self 

      if parser.parse() { 
       dispatch_async(dispatch_get_main_queue()) { 
        completionHandler(self.feeds, nil) 
       } 
      } else { 
       dispatch_async(dispatch_get_main_queue()) { 
        completionHandler(nil, parser.parserError) 
       } 
      } 
     } 
     task.resume() 

     return task 
    } 

    // NSXMLParserDelegate methods implemented here 

} 

Затем вы можете использовать синтаксис обработчика завершения, чтобы указать, что вы хотите делать, когда сетевой запрос и синтаксический анализ делается:

let URL = NSURL(string: "...") 
let myRssParser = ParserManager() 
myRssParser.parse(URL) { feeds, error in 
    guard feeds != nil else { 
     print(error) 
     return 
    } 

    // use `feeds` here, e.g. 

    self.feeds = feeds   // update your local property 
    self.tableView.reloadData() // and reload the table 
} 

// but don't use `feeds` here, since it won't be done by the time we get here 
+0

Ого, спасибо за усилие! Я постараюсь это –

+0

FYI, перемещая URL-адрес из метода 'init' и в параметр' parse'-метода, вы можете получить значительное дальнейшее упрощение (исключить 'init 'метод полностью, удалите кучу свойств и т. д.). См. исправленный ответ. – Rob

2

Исправление должно выглядеть следующим образом:

let myRssParser = ParserManager(URL: data) as! ParserManager 

Или, может быть, как это, зависит от того, как ParserManager было написано:

let myRssParser = ParserManager(url: data) as! ParserManager 

Существует даже вероятность, что вам не нужно использовать имя аргумента:

let myRssParser = ParserManager(data) as! ParserManager 
+1

Это не я, конечно. Теперь он говорит, что в вызове есть дополнительный аргумент «URL». Помогло ли это, если я добавлю свой код парсера в свой первоначальный пост? –

+0

Обновлен мой ответ. – Moritz

+0

Похоже, спасибо, спасибо! Но теперь есть проблема с преобразованием NSURL в ожидаемый(), поэтому мне кажется, что мне нужно заглянуть в мой код ParserManager. –

Смежные вопросы