Вызов `print` внутри NSView открывает диалоговое окно печати

Это странно. У меня есть простой заполнитель раскадровки с GridView для атрибута имени класса.

class GridView: NSView {

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        print("coder: \(coder)")
    }

    override func drawRect(dirtyRect: NSRect) {
        let rect = NSBezierPath(rect: dirtyRect)
        NSColor.redColor().setFill()
        rect.fill()
    }
}

Это работало, как и ожидалось, только с реализованным drawRect, но после того, как я добавил инициализатор, он начал открывать диалоговое окно печати каждый раз, когда я запускаю приложение.

Диалоговое окно печати

Почему это происходит и как правильно реализовать инициализатор раскадровки для пользовательского представления?


person Morgan Wilde    schedule 27.06.2015    source источник
comment
Вы пытались удалить оператор print? может очень странный баг...   -  person luk2302    schedule 27.06.2015
comment
Ух ты! Вы правы, print причина, по которой это происходит... Это действительно уму непостижимо!   -  person Morgan Wilde    schedule 27.06.2015
comment
ну, он просто не должен этого делать, печать должна делать что-то совсем другое... :D   -  person luk2302    schedule 27.06.2015
comment
Связано: Выбор глобальной или объектной функции.   -  person Martin R    schedule 27.06.2015


Ответы (3)


Вызов print() делает что-то другое, как и должно быть, точнее: что-то другое, как вы ожидаете. Он вызывает NSView print(sender: AnyObject?) вместо печати журнала. Вы можете рассматривать это как ошибку или, по крайней мере, как довольно неожиданное поведение, поскольку Swift.print(...) обычно используется гораздо чаще.

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

Взгляните на эту запись на форуме разработчиков Apple.

На самом деле это не ошибка, поскольку вызов print, который является «ближе» в текущем контексте, безусловно, является правильным способом. Вызов родителя print намного более разумен, чем вызов любого другого print. Смущает только тот факт, что вы обычно используете печать other, поскольку в целом вас не волнует, в какой области находится журналирование print — оно просто работает. Если вы думаете наоборот и хотите использовать печать print вашего родителя, это будет намного более запутанным, если вы явно заявите, что хотите использовать родителей. print, а не Swift.print(...).

Единственным "решением" было бы использование разных имен для двух функций, чего, скорее всего, не произойдет.

person luk2302    schedule 27.06.2015
comment
Забавно то, что в треде на странице, на которую вы ссылаетесь, люди считают это certainly not a bug. :) - person Morgan Wilde; 27.06.2015
comment
@MorganWilde да, именно поэтому я расширил свой ответ - возможно, я захочу удалить слово об ошибке, потому что вести себя таким образом просто странно, но несколько разумно. - person luk2302; 27.06.2015
comment
Это ошибка. Отладка print используется намного интенсивнее, чем print метод печати Cocoa, поэтому фреймворк должен что-то делать с этим. Это просто плохой дизайн. - person Morgan Wilde; 27.06.2015
comment
@MorganWilde вроде того, но только с точки зрения компилятора это на самом деле не ошибка, потому что вызов печати объекта, в котором вы сейчас находитесь, на самом деле является более правильным способом, чем вызов какой-то случайной статической печати, которая определена где-то еще. - person luk2302; 27.06.2015
comment
Конечно, здесь виноват не компилятор, а метод печати в этих классах Cocoa, который нужно изменить. ИМХО - person Morgan Wilde; 27.06.2015
comment
@MorganWilde, может быть, да. Но будет довольно сложно изменить имя или параметры некоторых функций, которые уже активно используются. Я думаю, что может быть слишком поздно для этого :/ - person luk2302; 27.06.2015
comment
Swift2 только что вышел, так что еще не поздно. Единственная причина, по которой эти методы сбивают с толку, заключается в том, что в Cocoa есть AnyObject? в подписи. Изменив это на что-то более разумное, мы могли бы избавить нас от этой глупой потребности в пространстве имен глобальной функции. - person Morgan Wilde; 27.06.2015
comment
@MorganWilde, вы не справитесь с этой проблемой, NSView.print должен просто иметь возможность печатать что угодно, а Swift.print должен иметь возможность печатать что угодно. Единственным жизнеспособным вариантом было бы переименовать один из них. Я сомневаюсь, что это произойдет, даже если я думаю, что это может быть хорошей идеей. - person luk2302; 27.06.2015
comment
Это ошибка или, по крайней мере, глупое дизайнерское решение Apple. Иногда print вызывает диалоговое окно печати, а иногда вызывает println. Что, черт возьми, было не так с println? - person iphaaw; 07.08.2015

Причина, по которой он вызывает диалоговое окно печати, заключается в том, что Swift 2, по-видимому, имеет два метода с одинаковой сигнатурой.

введите здесь описание изображения

person Morgan Wilde    schedule 27.06.2015

Это довольно старая тема, но я должен добавить, что вы можете написать:

Swift.print("something")

и вы бы использовали функцию «печать журнала» вместо функции просмотра.

person Bruno Garelli    schedule 26.08.2017