AppDelegate applicationDidFinishLaunching не называется [duplicate]

Однако источником вашей ошибки является то, что вам нужно поместить полную строку JSON в кавычки. Ниже будет исправлен ваш пример:

<!doctype HTML>
<html>
    <head>
    </head>
    <body>
        <script type="text/javascript">
            var cur_ques_details ='{"ques_id":"15","ques_title":"jlkjlkjlkjljl"}';
            var ques_list = JSON.parse(cur_ques_details);
            document.write(ques_list['ques_title']);
        </script>
    </body>
</html>

Как уже отмечали другие респонденты, объект уже разбирается в объект JS, поэтому вам не нужно его разбирать. Чтобы продемонстрировать, как выполнить одно и то же без разбора, вы можете сделать следующее:

<!doctype HTML>
<html>
<head>
</head>
    <body>
        <script type="text/javascript">
            var cur_ques_details ={"ques_id":"15","ques_title":"jlkjlkjlkjljl"};
            document.write(cur_ques_details.ques_title);
        </script>
    </body>
</html>
9
задан Zoyt 12 October 2016 в 20:51
поделиться

3 ответа

Вам нужно сделать несколько вещей здесь

  1. Удалить NSMainStoryboardFile ключ / значение из plist
  2. Создайте подкласс NSApplication и назначьте его кнопке Principal Class (NSPrincipalClass).

Имя должно быть полностью соответствующим имени вашего модуля.

  1. Вручную создать экземпляр вашего делегата в подклассе NSApplication и назначьте его свойству delegate.

Убедитесь, что вы держите ссылку на свой объект делегата. Ive просто использовал здесь let.

class GrookApplication: NSApplication {

    let strongDelegate = AppDelegate()

    override init() {
        super.init()
        self.delegate = strongDelegate
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

, например, простой делегат.

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    override init() {
        super.init()
        print("wassup")
        //conceptual proof of life init override
        //wait until applicationDidFinishLaunching , specially for UI
    }

    var window: NSWindow!
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print("yo! I'm alive")
        window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 200, height: 200), styleMask: .titled, backing: .buffered, defer: false)
        window.makeKeyAndOrderFront(nil)
    }

}

EDIT 2018 Verified High Sierra

НЕ пытайтесь инициализация окна или просмотра контроллера внутри init, это приводит к двойным проблемам инициализации приложений и сбоям. Приложение не закончило запуск на этом этапе. Подождите, пока applicationDidFinishLaunching не запустит какие-либо значительные операции.

13
ответ дан Warren Burton 19 August 2018 в 16:15
поделиться
  • 1
    как вы держите сильную ссылку? Я пробовал это, и все работало нормально - окно было показано, но когда я попытался установить styleMask окна на .titled, он дал мне исключение, сказав Assertion failure in -[X.XApplication init], /Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1504.82.104/AppKit.subproj/NSApplication.m:1778 2017-04-08 13:25:35.761585+0100 X[9073:1059806] [General] An uncaught exception was raised 2017-04-08 13:25:35.761601+0100 X[9073:1059806] [General] Creating more than one Application. – Tyler Durden 8 April 2017 в 12:35
  • 2
    @TylerDurden сильная ссылка делается с помощью var или let. Если вы этого не сделали, то слабая ссылка делегата высвободит экземпляр. т. е. это self.delegate = AppDelegate() не будет работать. Что касается вашего другого вопроса, не видя ваш код, я не знаю. Я подозреваю, что вы пытались сделать это [NSApplication sharedApplication].window, и он не работает по причинам. – Warren Burton 9 April 2017 в 10:08
  • 3
    Имейте в виду, что этот метод не работает на OS X Yosemite :) – Alex Sieroshtan 13 March 2018 в 16:34

В случае, если кто-то ищет версию Swift (на основе ответа @WarrenBurtons).

AppDelegate

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var window: NSWindow?

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        window = NSWindow(contentViewController: RootViewController())
        window?.makeKeyAndOrderFront(self)
    }
}

class RootViewController: NSViewController {
    override func loadView() {
      self.view = NSView()
      self.view.frame = NSRect(x: 0, y: 0, width: 600, height: 400)
  }
}

Подкласс NSApplication

import Cocoa

class Application: NSApplication {
    let strongDelegate = AppDelegate()

    override init() {
        super.init()
        self.delegate = strongDelegate
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Запись Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <key>NSPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).Application</string>
    ...
</dict>
</plist>

Я также создал для этого смысл, чтобы я был в курсе новых версий Xcode / Swift. https://gist.github.com/florieger/7ac5e7155f6faf18666f92f7d82f6cbc

Изменить: обязательно удалите Main.storyboard / MainMenu.xib, в противном случае вы можете оказаться в двух Windows в отладчике пользовательского интерфейса.

0
ответ дан florieger 19 August 2018 в 16:15
поделиться

Принимаемый ответ Уоррена Бертона, использующий сильную ссылку на @NSApplicationMain -занятый экземпляр AppDelegate, больше не работает. Я сам подтвердил это на OS X High Sierra, и Алекс Сироштан прокомментировал, что он тоже не работает в OS X Yosemite. Эта точка отказа, как заметил Тайлер Дюрден, была в этом сообщении:

Assertion failure in -[X.XApplication init], /Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1504.82.104/AppKit.subproj/NSApplication.m:1778
2017-04-08 13:25:35.761585+0100 X
[9073:1059806][General] An uncaught exception was raised 2017-04-08 13:25:35.761601+0100 X
[9073:1059806][General] Creating more than one Application

Я очень долго боролся с этим сам, но придумал два современных решения количество эксперимента.

Вариант 1: продолжить использование @NSApplicationMain с помощью обходного пути

Я обнаружил, что вы можете изменить код принятого ответа для работы вокруг ошибка. Способ сделать это - не вызвать метод super.init() в вашем классе с именем AppDelegate.

Что?

Действительно. Я думаю, что есть слишком нетерпеливое утверждение, подсчитывающее количество шагов, сделанных AppDelegate (или какая-то логика вдоль этих строк), и поэтому рассчитывается вызов super.init(), а также завершение блока override init(). У вас есть два варианта обходных путей:

  1. Не называть super.init(): это действительно возможно, а полностью здорово для NSObject, по крайней мере, в macOS. Однако вы теряете возможность ссылаться на self в блоке override init().
  2. Не переопределять init() вообще: рассмотрите возможность выполнения процесса инициализации во время жизненного цикла, например applicationWillFinishLaunching(:).

Я не рекомендую ни одно из них, конечно.

Вариант 2: отказаться от метода @NSApplicationMain вообще

@NSApplicationMain - это просто макрос, который мы можем приблизить. К счастью, я столкнулся с сообщением Джеймса Ф. Фишера в блоге , объясняющим, как это сделать.

Если вы написали @NSApplicationMain в любом месте, удалите его, прежде чем приступить к выполнению этих инструкций.

Нет необходимо изменить ваш файл Info.plist

Параметр key: value для NSPrincipalClass должен сохранять свое значение по умолчанию:

<key>NSPrincipalClass</key>
<string>NSApplication</string>

Вместо подкласса использовать main.swift NSApplication ]

Файл ДОЛЖЕН называться main.swift; это специальное исключение для правила Swift для «Выражения не допускаются на верхнем уровне».

import Cocoa

let myApp: NSApplication = NSApplication.shared
let myDelegate: AppDelegate = AppDelegate()
myApp.delegate = myDelegate
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

Логика

Джеймс Х Фишер объясняет, ссылаясь NSApplication документация :

[Docs]

Каждое приложение должно иметь ровно один экземпляр NSApplication (или подкласс NSApplication). Функция main() вашей программы должна создать этот экземпляр, вызвав метод класса shared().

[James]

Сначала main.swift запускает NSApplication.shared и назначает этот NSApplication объект myApp. Обратите внимание, что документация относится к функции main(), хотя в Swift нет ни одного! Эквивалентным является файл main.swift.

Затем main.swift создает экземпляр класса AppDelegate и назначает его как .delegate в myApp. Теперь вы можете увидеть, почему проект по умолчанию выбирает вызов класса AppDelegate: он установлен как .delegate на NSApplication.

Наконец, main.swift вызывает функцию NSApplicationMain(...). .. Функция NSApplicationMain(...) является точкой входа для приложений Cocoa. NSApplicationMain(...) никогда не возвращается; вместо этого он устанавливает цикл событий пользовательского интерфейса и, в конечном счете, выходит из функции C exit(...).

Дополнительно этот пост StackOverflow подробно описывает, почему sharedApplication исправляет ошибку «Создание нескольких приложений».

... Это все, что вам нужно! Надеюсь, это поможет кому-то еще.

0
ответ дан Jamie Birch 19 August 2018 в 16:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: