2014-06-13 11 views
12

Sto sviluppando una piccola app basata su UITableView in Swift. Ho iniziato codificare alcuni array di base in quanto tali (inclusa è la dichiarazione della classe base e la dichiarazione UITableView presa:Lettura Swift Plist e inizializzazione di array come oggetti per la chiave

import UIKit 

class ScenesViewController: UITableViewController { 

@IBOutlet var myTableView: UITableView 

var sceneName = ["Scene 1", "Scene 2", "Scene 3", "Scene 4", "Scene 5"] 
var sceneDetail = ["Hi", "Hello", "Bye", "My Bad", "Happy"] 

Questo codice è all'interno di un UITableViewController che ha una presa che è tutto collegato a un UITableView. . ho creato un plist per questo chiamato "Scenes.plist" e ho cercato di sostituire il codice in Objective-C, farei questo:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Scenes" ofType:@"plist"]; 

NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
sceneName = [dict objectForKey:@"SceneName"]; 
sceneDetail = [dict objectForKey:@"SceneDetail"]; 

ho iniziato a fare questo in Swift come questo:

let path = NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist") 

let dict = NSDictionary(contentsOfFile:path) // Error: 'ScenesViewController.Type' does not have a member named 'path' 

Ho setacciato Internet per trovare una soluzione ma non sono riuscito a trovarne uno. Così ho preso il prossimo corso di azione - un 'quasi' one-liner:

let dict = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist")) 

var sceneName = dict["SceneName"] // Error: 'ScenesViewController.Type' does not have a member named 'dict' 

Ora, l'unica soluzione che posso quasi ricorrere a sta avendo tutto questo su una riga per ogni matrice:

var sceneName = NSDictionary(contentsOfFile: 
    NSBundle.mainBundle().pathForResource("Scenes", ofType:"plist").objectForKey("SceneName") 
// Warning: Variable 'sceneName' inferred to have type 'AnyObject!', which may be unexpected 
// Fix-It: Add an explicit type annotation to silence this warning (var sceneName: AnyObject! = ...) 

Così ho aggiunto l'annotazione del tipo esplicito solo per scoprire che c'erano più errori. All'interno della funzione cellForRowAtIndexPath::

override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? { 
    let cell: UITableViewCell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell 

    // Configure the cell... 

    cell.textLabel.text = sceneName[indexPath!.row] // Error: could not find member 'row' 
    return cell 
} 

In realtà ci sono due errori ; Non so se questo è accidentalmente duplicato o meno. Il successivo errore (s) sono nel metodo della prepareForSegue:sender::

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) { 
    if segue?.identifier == "ShowDetails" { 
     var detailVC: ScenesDetailViewController = segue!.destinationViewController as ScenesDetailViewController 

     var myIndexPath: NSIndexPath = myTableView.indexPathForSelectedRow() 

     var row: Int = myIndexPath.row 

     detailVC.detailModal = [sceneDetail[row], sceneName[row]] // Error: Could not find an overload for 'subscript' that accepts the supplied arguments 
    } 
} 

caso, ci sono due errori; tuttavia, credo che questo sia perché sceneDetail e sceneName sono entrambi utilizzati. Sembrano esserci errori dappertutto con la lettura e l'uso di file in file che non sono presenti (o che non ho trovato) in Objective-C.

Grazie in anticipo,

-KodInc

+0

le proprietà 'row' e' section' di 'NSIndexPath' sono definite in' UIKit' e non 'Foundation'. L'aggiunta di 'import UIKit' al tuo file risolve questo problema? – Jack

+0

@JackWu 'UIKit' è già stato importato; è la prima riga – KodInc

risposta

19

per risolvere il problema iniziale, messo il codice all'interno di un func, come:

var memoryName = [] 
var memoryDetail = [] 

override func awakeFromNib() { 
    super.awakeFromNib() 

    let path = NSBundle.mainBundle().pathForResource("Memories", ofType:"plist") 
    let dict = NSDictionary(contentsOfFile:path) 

    memoryName = dict["MemoryName"] as Array<String> 
    memoryDetail = dict["MemoryDetail"] as Array<String> 
} 
+0

Grazie. Questo ha aiutato il problema originale. Tuttavia, gli errori che seguirono dovevano essere risolti manualmente. Puoi spiegare perché la tua spiegazione funziona contro quello che stavo facendo male? Inoltre, diretto a StackOverflow, se la parte delle risposte della mia domanda è senza spiegazione (come fa questa risposta), lo accetto? - KodInc – KodInc

1

È possibile risolvere questo spostando il codice in un funzione chiamata dopo l'inizializzazione degli oggetti.

Le proprietà vengono inizializzate come parte dell'inizializzazione dell'oggetto. Hai creato percorso e dettato come proprietà e stai tentando di inizializzarli con un codice che non soddisfa i requisiti per l'inizializzazione.

Un inizializzatore non può chiamare qualsiasi metodo di istanza, leggere i valori delle proprietà dell'istanza o consultare sé come valore fino a dopo la prima fase di inizializzazione è completata.

-La Swift linguaggio di programmazione - inizializzazione - controllo di sicurezza 4

Inoltre, sembra solamente vogliono e hanno bisogno sceneName e sceneDetail ad essere proprietà, in modo da poterli spostare completamente nell'ambito del metodo che usi per popolare sceneDetail e sceneName dopo l'inizializzazione.

È difficile per me dire che l'errore di pedice è esattamente perché non vedo quale tipo di dati deve contenere il contenuto VC.detailModal; anche così, sembra che il tipo di oggetto sbagliato sia passato nell'array detailModal. Una buona descrizione di questo problema è Swift and arrays

Problemi correlati