¿Qué significa "debilitar unir" un marco?

En Xcode, puedo establecer un marco para "Opcional" en lugar de "Obligatorio", lo que significa que el marco está débilmente vinculado.

¿Eso significa que el marco solo se incluye en el package cuando se importa en algún lugar?

Quiero enlazar débilmente algunos frameworks de debugging que utilizan API privada , y no quiero que aparezcan en la compilation de App Store.

Nota importante : esta respuesta se escribió antes de que se anunciara iOS 8. Si bien los detalles técnicos aún se aplican a los frameworks del sistema, ahora es posible crear sus propios frameworks vinculados dinámicamente que se envían dentro de su package de aplicaciones. Hay restricciones, por ejemplo, solo una aplicación y sus extensiones pueden vincularse a la misma instancia de un marco embedded, pero el hecho es que el marco personalizado y dinámicamente vinculado es posible desde iOS 8. Si desea get más información, consulte esta guía ( Uso de un marco incorporado para compartir código ) y la session 416 de WWDC 2014, Construcción de frameworks modernos .

Respuesta original : Ninguno de los frameworks (de la plataforma) está realmente " incluido en el package ". En cambio, su aplicación tiene una reference (" enlace ") a un marco una vez que lo agrega a la fase de compilation "Enlace binary con biblioteca". Los frameworks están preinstalados en los dispositivos. Cuando ejecuta una aplicación, todas las references del marco de la aplicación se resuelven mediante el linker dynamic (en el dispositivo), lo que significa que el código marco se carga para que su aplicación pueda usarlo.

Es posible que algunos frameworks no estén disponibles en todos los dispositivos que pretende soportar, por ejemplo, PassKit se introdujo en iOS 6. Si ejecuta una aplicación que se vincula con PassKit en un dispositivo con iOS 5, se bloquea inmediatamente después del lanzamiento, ya que el vinculador dynamic no puede Encuentra el marco en el dispositivo. Sin embargo, si debilita el enlace de PassKit, el linker dynamic establecerá todos los símbolos del marco en nil , si no se pudo encontrar el marco. Esto evita que la aplicación se bloquee y puede verificar la disponibilidad de los símbolos en time de ejecución, por ejemplo:

 if ([PKPass class]) { // Class is available - use it PKPass *pass = [[PKPass alloc] init]; } 

[PKPass class] es segura de usar en todos los dispositivos / sistemas ya que el símbolo de la class PKPass será nil en sistemas más antiguos, y la function de postría nil no es un problema en Objective-C.

Más información sobre la relación débil: la documentation de Apple

Para responder realmente a tu pregunta:

¿Eso significa que el marco solo se incluye en el package cuando se importa en algún lugar?

No. El marco siempre estará vinculado desde la aplicación. Solo cuando el marco no se encuentra en el dispositivo real, su aplicación se está ejecutando, entonces el marco no se cargará.

Una solución sería tener objectives separados para Debug y App Store Builds. Una alternativa es no utilizar la fase de compilation "Enlace binary con biblioteca" incorporada de Xcode, sino vincular los frameworks de debugging mediante las opciones de linker. Estos pueden especificarse para cada configuration (Depurar / Liberar / …) por separado, así:

Agregar marco a través de banderas de enlazador

Si desea vincularlo débilmente, use -weak_framework PassKit (PassKit, por supuesto, siendo solo un ejemplo aquí … inserte el nombre de su marco) en su lugar. Si su marco de debugging no está en uno de los directorys marco pnetworkingeterminados, es posible que deba proporcionar una ruta completa o modificar la ruta de búsqueda de Framework. Además, probablemente deberías usar macros para asegurarte de que ninguno de los códigos que usan el framework (s) de debugging lo haga a la compilation de App Store.

Editar : Otra opción desde Xcode 5 es usar @import <FrameworkName>; . De esta manera, puede dejar su fase "Link Binary …" vacía y desencadenar la vinculación de frameworks en el código. A continuación, puede utilizar macros como DEBUG para asegurarse de que algunos frameworks no se usen para comstackciones de App Store. Hay una excelente respuesta con respecto a @import .

Encontré un enlace débil cuando estaba usando iAds. El problema fue si uniría fuertemente el marco de iAds y ejecutaba la aplicación en un dispositivo con SDK que no soportaba iAds, entonces simplemente fallaba. Débil enlace permitió evitar los lockings. Sigo creyendo que incluso con un enlace débil, aún tiene que verificar el código si el marco está disponible o no.

¿Eso significa que el marco solo se incluye en el package cuando se importa en algún lugar?

Esto depende de cómo configuró sus esquemas o objectives.

Podría usar un solo esquema para depurar e include su marco opcional solo allí. Use otro esquema sin el marco opcional para la versión.

Ejemplo de esquema

ACTUALIZAR

Para hacer esto, base su nuevo esquema en una configuration de proyecto y configure OTHER_LDFLAGS como se describe en la respuesta de hagi .

Configuraciones y esquemas de proyectos