objective-c swift macros clang c-preprocessor

objective c - Alternativa de Swift para el diagnóstico de#pragma clang



objective-c macros (1)

Problema

Recientemente encontré una advertencia en una utilidad de terceros (WEPopover) en este fragmento de código:

_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

Esto generaba la siguiente advertencia:

warning: ''contentSizeForViewInPopover'' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations] _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;

Una solución temporal para esto en Objective-C es usar pragma clang diagnostic para silenciar el error (dejaré que el autor del código se ocupe de una solución verdadera). Así que revisé el código así:

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" _effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover; #pragma clang diagnostic pop

Pregunta

Lo cual funciona bien, pero esto me llevó a considerar qué pasa si existe alguna alternativa donde uno tendría que silenciar una advertencia positiva falsa similar cuando se codifica en Swift.

Consideraciones

He observado el hecho de que puedo desactivar tales advertencias en todo el proyecto (usando la configuración de Xcode), pero quiero considerar el problema en línea como se indicó anteriormente. También consideré agregar un #define en un archivo .bridging-header.h dentro de mi proyecto Swift y de alguna manera hacer uso de eso; sin embargo, estoy buscando una solución específica Swift para este problema. Entiendo que pragma ya no está disponible y he buscado SO y encontré preguntas similares pero no duplicadas.

RESOLUCIÓN ACTUALIZADA: Swift 2.0

La respuesta proporcionada maneja mi preocupación acerca de las advertencias en línea. El comando de disponibilidad debería permitir evitar tales problemas por completo, ya que uno sería advertido en tiempo de compilación.

El libro Swift de Apple declara definitivamente:

"Utiliza una condición de disponibilidad en una sentencia if o guard para ejecutar de forma condicional un bloque de código, dependiendo de si las API que quiere usar están disponibles en tiempo de ejecución. El compilador usa la información de la condición de disponibilidad cuando verifica que las API en ese "bloque de código están disponibles".

if #available(iOS 9, OSX 10.10, *) { // Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X } else { // Fall back to earlier iOS and OS X APIs }

"

Extracto de: Apple Inc. "The Swift Programming Language (Swift 2 Prerelease)". IBooks. https://itun.es/us/k5SW7.l "

Incluso se podría usar la declaración de guardia combinada con la disponibilidad para salir temprano del alcance a menos que se cumplan las condiciones disponibles.

guard #available(iOS 8.0, OSX 10.10, *) else { return }

Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Swift 2 Prerelease)." IBooks. https://itun.es/us/utTW7.l

Además, mis preocupaciones relacionadas con el manejo de macros se tratan como se indica a continuación. Teniendo en cuenta que Swift no tiene preprocesador, estas herramientas parecen ser el camino a seguir.

" Macros simples "

Donde típicamente usaste la directiva #define para definir una constante primitiva en C y Objective-C, en Swift usas una constante global. Por ejemplo, la constante definición #define FADE_ANIMATION_DURATION 0.35 se puede expresar mejor en Swift con let FADE_ANIMATION_DURATION = 0.35. Debido a que las macros constantes simples se asignan directamente a las variables globales de Swift, el compilador importa automáticamente las macros simples definidas en los archivos fuente C y Objective-C.

Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Swift 2 Prerelease)." IBooks. https://itun.es/us/utTW7.l

" Macros complejas "

Las macros complejas se usan en C y Objective-C, pero no tienen contraparte en Swift. Las macros complejas son macros que no definen constantes, incluidas las macros parecidas a funciones entre paréntesis. Utiliza macros complejas en C y Objective-C para evitar restricciones de verificación de tipos o para evitar volver a escribir grandes cantidades de código repetitivo. Sin embargo, las macros pueden dificultar la depuración y la refactorización. En Swift, puede usar funciones y genéricos para lograr los mismos resultados sin ningún compromiso. Por lo tanto, las "macros complejas que se encuentran en los archivos fuente C y Objective-C no están disponibles para su código Swift".

Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Swift 2 Prerelease)." IBooks. https://itun.es/us/utTW7.l

El desarrollador de la API podrá marcar la disponibilidad de funciones en Swift usando:

available(iOS 8.0, OSX 10.10, *) func useShinyNewFeature() { // ... }

Extracto de: Apple Inc. "Uso de Swift con Cocoa y Objective-C (Swift 2 Prerelease)." IBooks. https://itun.es/us/utTW7.l

Agregar estos marcadores a funciones reescritas para Swift parece una buena manera de mantener la compatibilidad con versiones anteriores para Frameworks. La combinación de guardia / disponible permitirá a los usuarios de esos marcos ajustar la lógica según sea necesario. Lo que hace que mi mente se sienta a gusto con el manejo de las advertencias en línea, la recuperación de la API y las macros en general.


A partir de la versión 2.0 (actualmente en versión beta a partir de esta redacción), Swift aún no incluye un preprocesador y no parece cambiar pronto (si es que lo hace). Las capacidades beneficiosas que permiten los preprocesadores están integradas en el lenguaje de varias maneras (no las voy a abarcar todas aquí, vea los documentos) y son funciones de nivel de tiempo de compilación.

Hay dos características que quiero mencionar (una vieja, una nueva) que pueden ser lo que estás buscando:

  1. Compilación condicional : tal como se describe en Utilización de Swift con Cocoa y Objective-C , puede implementar sentencias de compilación condicionales que le permiten compilar únicamente código dado ciertos sistemas operativos o arquitecturas de procesador. Si se ve algo como esto:
  1. Comprobación de la disponibilidad de la API : tal como se describe en el lenguaje de programación Swift , ahora puede verificar la disponibilidad de la API según la plataforma y la versión del sistema operativo. Esto le permitirá aprovechar las nuevas API mientras le permite manejar cuando esa característica no está disponible en una plataforma o SO más antiguo (o diferente). Puede usar esto para sub en una implementación alternativa o presentar una explicación al usuario. Si se ve algo como esto:

Estas herramientas (junto con muchas otras integradas en el lenguaje) deberían permitir a un desarrollador reemplazar las macros del preprocesador Objective-C y C. Personalmente, creo que son una gran mejora.