我正在开发一个mac osx应用程序,它具有从主故事板启动的初始窗口和viewcontroller。我想用我的视图替换storyboard加载的内容视图。 我这样做 -
func replaceContentView() {
parentViewController = MainViewController(nibName: "MainContainerView", bundle: nil)!
let fullScreenFrame = NSScreen.mainScreen()?.visibleFrame
self.initialWindow.setFrame(fullScreenFrame!, display: false, animate: false)
self.initialWindow.contentView = parentViewController! . view
}
这种方法的问题是默认的viewcontroller永远不会被释放。根本没有调用默认viewController的 deinit()。 这导致内存泄漏。那么如何完全删除默认内容视图和关联的viewcontroller?
答案 0 :(得分:0)
你可以用deinit方法编写代码,它可以帮到你。
deinit {
// perform the deinitialization
}
答案 1 :(得分:0)
您在NSWindow实例中的contentViewController仍然强烈支持其旧视图。您已在NSWindow实例上替换了仅属性。
澄清你做了什么:
您应该将新视图分配到contentViewController.view属性
这可能会有所帮助:
NSWindow.h
/* NSViewController Support */
/* The main content view controller for the window. This provides the contentView of the window. Assigning this value will remove the existing contentView and will make the contentViewController.view the main contentView for the window. The default value is nil. The contentViewController only controls the contentView, and not the title of the window. The window title can easily be bound to the contentViewController with the following: [window bind:NSTitleBinding toObject:contentViewController withKeyPath:@"title" options:nil]. Setting the contentViewController will cause the window to resize based on the current size of the contentViewController. Autolayout should be used to restrict the size of the window. The value of the contentViewController is encoded in the NIB. Directly assigning a contentView will clear out the rootViewController.
*/
@availability(OSX, introduced=10.10)
var contentViewController: NSViewController?
/* The view controller for the window's contentView. Tracks the window property of the same name.
*/
@property (strong) NSViewController *contentViewController NS_AVAILABLE_MAC(10_10);
但是,如果在启动时执行此操作,您所执行的操作似乎不正确。
您可以将contentView的自定义子类设置为新的nsview子类,该子类可以从另一个XIB加载它的视图(不需要故事板)。
抽象示例:
class CustomView: NSView {
@IBOutlet var contentView: NSView!
@IBOutlet weak var label: NSTextField!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initSubviews()
}
override init(frame: CGRect) {
super.init(frame: frame)
initSubviews()
}
func initSubviews() {
let nib = NSNib(nibName: "CustomView", bundle: nil)
nib.instantiateWithOwner(self, topLevelObjects: nil)
contentView.frame = bounds
addSubview(contentView)
}
}
PS:topLevelObjects设置为nil,因为你持有强大的contentView。所以不必担心内存管理。
答案 2 :(得分:0)
故事板不处理视图,它们处理视图控制器。情节提要板将视图加载到窗口中时的作用是创建一个NSViewController
然后进入
windowController.contentViewController = theViewController
这也隐式地插入theViewController.view
作为窗口的内容视图。这样做也是一样,一切都会好起来的。
Marek的示例是错误的,因为CustomView
不应该是NSView
的子类,它应该是CustomViewController
的类,该类拥有包含标签等的视图。作为奖励,{ {1}}还将为您加载XIB。
或者,您可以设置NSViewController
(这将删除旧的视图控制器及其内容视图),然后设置内容视图。但是,实际上,为什么正是在windowController.contentViewController = nil
打算使用的框架下使用框架?