2014-12-11 13 views
7

Chcę wdrożyć listę źródeł za pomocą NSOutlineView w projekcie Swift.Awaria NSOutlineView, gdy metoda delegowania isGroupItem jest używana ze Swiftem

Poniższy kontroler widoku działa dobrze, gdy metoda delegowania isGroupItem nie jest wywoływana. Jednak wiele elementów __NSMallocBlock__ zostanie zwróconych, gdy użyta zostanie metoda isGroupItem. Nie mam pojęcia, skąd pochodzą te elementy. Elementy, które podałem, są tylko ciągami.

class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate { 

let topLevel = ["1", "2"] 
let secLevel = ["1": ["1.1", "1.2"], "2": ["2.1", "2.2"]] 

func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int { 
    if let str = item as? String { 
     let arr = secLevel[str]! as [String] 
     return arr.count 
    } else { 
     return topLevel.count 
    } 
} 

func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool { 
    return outlineView.parentForItem(item) == nil 
} 

func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject { 
    var output: String! 
    if let str = item as? String { 
     output = secLevel[str]![index] 
    } else { 
     output = topLevel[index] 
    } 
    return NSString(string: output) 
} 

func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? { 
    return item 
} 

func outlineView(outlineView: NSOutlineView, isGroupItem item: AnyObject) -> Bool { 
    return (outlineView.parentForItem(item) == nil) 
} 

func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? { 
    return outlineView.makeViewWithIdentifier("HeaderCell", owner: self) as NSTextField 
} 
} 

Projekt próbki można pobrać here

+0

Pachnie jak błąd. Jeśli zwrócisz 'true', to ulegnie awarii. Jeśli zwrócisz 'false', to pokazuje linię rodzica jako' malloc ... ' –

+0

To prawdopodobnie jest błąd; powinien "po prostu działać", ale nie działa. Zobacz moją odpowiedź (wkrótce). –

Odpowiedz

5

To pytanie zostało odebrane przez Kena Tomaszom na forum jabłko programisty. Tutaj wyodrębniono to, co powiedział:

Elementy dostarczane do widoku konspektu muszą być trwałe. Musisz również zwrócić tę samą pozycję za każdym razem dla danego rodzica i indeksu. Nie można zwrócić obiektów, które zostały utworzone ad hoc, tak jak robisz w -outlineView: child: ofItem: gdzie wywołujesz konstruktor wygody NSString.

Współpracuje po utrzymujących obiektów źródła danych następująco:

let topLevel = [NSString(string: "1"), NSString(string: "2")] 
let secLevel = ["1": [NSString(string: "1.1"), NSString(string: "1.2")], "2": [NSString(string: "2.1"), NSString(string: "2.2")]] 

następnie powrócić NSString zapisanego w outlineView: metodę źródło danych: dziecko: ofItem.

+0

Dzięki. To pomogło. Nigdy bym się nie domyślił. – nspire

+0

I błąkał się z tym trochę więcej. Zobacz tutaj: http://stackoverflow.com/questions/24828553/swift-code-to-use-nsoutlineview-as-file-system-directory-browser/27626466#27626466 –

+0

Myślę, że ważne jest, aby zrozumieć * dlaczego * to Prace. Zobacz moją odpowiedź. –

8

Po sprawdzeniu dokumentacji NSOutlineView zobaczysz, że przechowuje tylko wskaźniki; nie zachowuje obiektów zwróconych z elementu child: ofItem: delegate method. Więc, kiedy to zrobić linię:

return NSString(string: output) 

wracasz nowy NSString instancji, który jest szybko uwalniana (ponieważ widok konspektu nie zachowuje go). Po tym momencie, kiedy tylko zadasz pytania dotyczące przedmiotów, otrzymasz awarię, ponieważ NSString został zwolniony.

Rozwiązanie jest proste: przechowuj NSStrings w tablicy i zwracaj te same instancje za każdym razem.

Corbin

0

To dlatego NSOutlineView prace z przedmiotów odziedziczone NSObject i Swift ciąg jest niezgodny typ.

Powiązane problemy