2016-10-26 4 views
0

Как правильно загрузить NSView из Xib?Как загрузить NSView из Xib с Swift 3

Мой код:

var topLevelArray: NSArray? = nil 
let outputValue = AutoreleasingUnsafeMutablePointer<NSArray>(&topLevelArray) 

if Bundle.main.loadNibNamed("RadioPlayerView", owner: nil, topLevelObjects: outputValue) { 
    let views = outputValue.pointee 
    return views.firstObject as! RadioPlayerView 
} 

topLevelArray = nil 
return nil 

Проблема заключается в «outputValue» является указателем авто-релиз, и как только я вернусь из функции, аварии с программой ACCESS_BAD_ADDRESS

+0

сохранить сильную ссылку, используя свойство класса, а затем он не будет освобожден. И постарайтесь лучше понять ARC и управление памятью. – Volker

+0

Да, это правда. Но я не хочу поддерживать сильную ссылку, я просто хочу загрузить View и сделать. На самом деле, я исправил проблемы. это довольно просто, просто удалить переменную указатель: пусть outputValue = AutoreleasingUnsafeMutablePointer (& topLevelArray) и просто Bundle.main.loadNibNamed ("RadioPlayerView", владелец: ноль, topLevelObjects: & topLevelArray) –

ответ

1

Я сделал протокол и расширение, чтобы сделать это:

import Cocoa 

protocol NibLoadable { 
    static var nibName: String? { get } 
    static func createFromNib(in bundle: Bundle) -> Self? 
} 

extension NibLoadable where Self: NSView { 

    static var nibName: String? { 
     return String(describing: Self.self) 
    } 

    static func createFromNib(in bundle: Bundle = Bundle.main) -> Self? { 
     guard let nibName = nibName else { return nil } 
     var topLevelArray: NSArray? = nil 
     bundle.loadNibNamed(NSNib.Name(nibName), owner: self, topLevelObjects: &topLevelArray) 
     guard let results = topLevelArray else { return nil } 
     let views = Array<Any>(results).filter { $0 is Self } 
     return views.last as? Self 
    } 
} 

Использование:

final class MyView: NSView, NibLoadable { 
    // ... 
} 

// ... где-нибудь еще:

let myView: MyView? = MyView.createFromNib()