Class Foo se implementa tanto en MyApp como en MyAppTestCase. Uno de los dos será usado. Cuál es indefinido

Recientemente comencé a probar mi aplicación. Este proyecto (en Xcode4) se creó sin un paquete de prueba unitario, así que tuve que configurarlo. He seguido los pasos desde aquí: http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html Y estaba funcionando bien para las clases simples, pero ahora estoy tratando de probar una clase que depende en otro y eso en otro, etc.

Primero recibí un error del enlazador, así que agregué archivos *.m al objective del caso de prueba, pero ahora recibo una advertencia para cada clase que bash probar:

Class Foo se implementa tanto en MyApp como en MyAppTestCase. Uno de los dos será usado. Cuál es indefinido

Me pregunto, ¿por qué es así? ¿Como puedo resolver esto? Tal vez me perdí algo cuando establecí el objective de la prueba de unidad?

Editar – La solución

  • Establezca “Bundle Loader” correctamente en $(BUILT_PRODUCTS_DIR)/AppName.app/AppName

  • Establezca “Símbolos ocultos por defecto” en NO (en Configuración de comstackción de la aplicación de destino). Aquí es de donde provienen los errores del enlazador porque es SÍ por defecto. ¡He estado luchando con esto por tanto tiempo !.

Fuente: ¿ Error de enlace para pruebas unitarias con XCode 4?

Class Foo se implementa tanto en MyApp como en MyAppTestCase. Uno de los dos será usado. Cuál es indefinido

Me pregunto, ¿por qué es así?

porque ambas imágenes (la aplicación y el paquete de prueba de la unidad) definen la implementación de la clase. la clase se carga dinámicamente en el tiempo de ejecución objc. el tiempo de ejecución de objc usa un espacio de nombre plano. cómo funciona esto:

  • el binario está cargado, comenzando con sus dependencias
  • a medida que se carga cada binario, las clases objc se registran con el tiempo de ejecución objc
  • si una clase con un nombre específico se carga dos veces, el comportamiento no está definido. una implementación de una clase (con nombres idénticos) se puede cargar en el tiempo de ejecución objc.

el problema típico aquí es que se le devolverá una implementación: es probable que su aplicación falle cuando el tipo entra en conflicto (cuando la clase no proviene del mismo archivo fuente).

normalmente evita esto al cambiar el nombre de una clase o exportar la clase en una imagen. renombrar la clase obviamente no se aplica a su caso. tiene un archivo Foo.m que está siendo comstackdo, exportado y cargado por dos imágenes cuando debería estar en uno.

esto debe ser interpretado por usted como un error de vinculador de símbolo duplicado. aunque la implementación es el mismo archivo fuente (y la implementación es la misma): este es un problema que debe solucionar.

¿Como puedo resolver esto?

si Foo.m es una clase de la aplicación, debe eliminar (no comstackr y vincular) Foo.m de la prueba unitaria. si es parte de la prueba de la unidad, no la compile y vincule con el objective de prueba de la unidad.

luego, siga las instrucciones en la publicación para vincular / cargar su prueba unitaria a la aplicación. está en esta área general de la publicación: donde “WhereIsMyMac” es el nombre de la aplicación que está probando por unidad. Esto permitirá que el objective de la prueba se vincule con la aplicación (por lo que no obtendrá errores del enlazador al comstackr). la parte importante es que los archivos de prueba se comstackn en el objective de la prueba de la unidad (solo) y las clases de la aplicación se comstackn y se vinculan a la aplicación. no puedes simplemente agregarlos, se vinculan y se cargan dinámicamente.

Tal vez me perdí algo cuando establecí el objective de la prueba de unidad?

Del artículo que vinculó:

Nota: El objective de prueba es un objective separado. Esto significa que debe tener cuidado con la membresía objective. Todos los archivos fuente de la aplicación deben agregarse únicamente al objective de la aplicación. Los archivos de códigos de prueba se deben agregar solo al objective de prueba.

la parte que te equivocaste es probablemente las fases de enlace y carga del paquete de prueba de la unidad.

Si está utilizando Cocoapods, su archivo de archivo solo necesita las dependencias en la sección para el objective principal, no los objectives de prueba. Si agrega dependencias duplicadas para los objectives de prueba, obtendrá el mensaje de error de OP.

 target 'MyProject' do pod 'Parse' end target 'MyProjectTests' do end target 'MyProjectUITests' do end 

Para mí, todo lo que tenía que hacer era desmarcar la checkbox que hace que la clase Foo sea miembro del objective de prueba de la unidad. No debería ser un miembro de ambos objectives, y debería verse así:

Membresía objetivo

En caso de que no pueda ver la imagen, se trata de una captura de pantalla del panel “Membresía de destino” de Xcode. Hay dos objectives: uno con un ícono de aplicación “A” y el nombre de la prueba. El otro es el objective de la prueba unitaria y tiene un icono de prueba de unidad:

 Target Membership [X] Foo [ ] FooTests 

Para mí, esto sucedió porque me desplegué en el dispositivo y luego en el simulador ya que tengo NSZombies habilitado. La solución fue cambiar a la configuración del simulador y hacer un Producto -> Limpiar, luego cambiar a la configuración del dispositivo y hacer lo mismo. El error desapareció Tiene que ver con la memoria caché de comstackción.

La razón es que anulas RUNPATH_SEARCH_PATHS de la RUNPATH_SEARCH_PATHS de RUNPATH_SEARCH_PATHS de tu aplicación definida en otro objective.

Solución:

Vaya a su destino de aplicación y busque la RUNPATH_SEARCH_PATHS comstackción RUNPATH_SEARCH_PATHS y use el indicador $(inherited) para ambos: Depurar y liberar

Nos encontramos con los mismos problemas, mi situación es que la clase NSNotification se implementa en ambos /System/Library/Frameworks/Foundation.framework/Foundation, ¿hay algún tipo que se encuentre con el mismo problema? Cualquier dirección o consejo se aplicará.