Como você pode implementar o método NSDocument -canCloseDocumentWithDelegate: shouldCloseSelector: contextInfo: in Swift?
Na minha aplicação, umNSDocument
hardware de missão crítica da subclasse - os usuários realmente não querem fechar um documento acidentalmente! Então eu implementeicanCloseDocumentWithDelegate…
para mostrar umaNSAlert
e pergunte antes de fechar.
Agora estou tentando implementar a mesma coisa em um aplicativo escrito em Swift.
Como a resposta é fornecida de forma assíncrona, o resultado "deveria fechar" é passado para um retorno de chamada em um delegado e não simplesmente retornado. Na documentação para-canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo:
, diz:
O método de retorno de chamada shouldCloseSelector deve ter a seguinte assinatura:
- (void)document:(NSDocument *)doc shouldClose:(BOOL)shouldClose contextInfo:(void *)contextInfo
Então, como existem 3 argumentos de tipos diferentes, não posso usar o simplesperformSelector:withObject:
métodos de estilo - você precisa usar o NSInvocation. Observe que o delegado é do tipoid
, e a assinatura acima não aparece em nenhum protocolo formal - você não pode simplesmente chamar o método normalmente. (Veja issopostagem na lista de discussão por exemplo, como isso deve ser feito)
Agora, o problema é que o NSInvocation não é permitido no Swift! Veja o blog Swift“O que aconteceu com o NSMethodSignature”:
Trazer as estruturas de cacau à Swift nos deu uma oportunidade única de examinar nossas APIs com uma nova perspectiva. Encontramos aulas que não nos encaixavam com os objetivos do Swift, geralmente devido à prioridade que damos à segurança. Por exemplo, algumas classes relacionadas à invocação de método dinâmico não são expostas no Swift, a saberNSInvocation
eNSMethodSignature
.
Parece uma coisa boa, mas cai quando um simplesNSDocument
A API ainda requer NSInvocation! A solução real para todo esse problema seria a Apple introduzir um novocanCloseDocument…
API usando um retorno de chamada em bloco. Mas até que isso aconteça, qual é a melhor solução?