Los guiones gráficos son más bien un dolor real desde la perspectiva del flujo de trabajo de git cuando varias personas colaboran en ellos. Por ejemplo, el XML en el archivo .storyboard tiene sus <document>
etiquetas toolsVersion
y systemVersion
atributos iniciales alterados por cualquier configuración que esté ejecutando el manipulador de archivos más reciente. Sincronizar las versiones de Xcode de todo el mundo parece ayudar con precisión toolsVersion
, pero systemVersion
cambia sin importar qué, dependiendo de la versión específica de Mac y / o OS X que el desarrollador esté ejecutando.
Esto es idiota, pero sobre todo inofensivo. Sin embargo, lo que nos preocupa es que en otros momentos se realizan automáticamente otros cambios en el guión gráfico simplemente abriéndolos después de a git pull
. Es decir, Alice realiza cambios en un guión gráfico, los confirma y los empuja al repositorio. Bob luego saca los cambios de Alice y abre el guión gráfico para realizar más cambios. En el momento en que abre el guión gráfico, el icono del archivo cambia inmediatamente a un estado modificado pero no guardado, y git status
muestra que se han producido varios cambios extraños. Todo esto sin que Bob haya cambiado nada o guardado el archivo él mismo.
El cambio automático más común que estamos viendo es la desaparición o reaparición de toda la <classes>
jerarquía de etiquetas cerca del final de un archivo de guión gráfico. No hemos descubierto qué está causando esto. Es posible que tengamos varias versiones localizadas de un guión gráfico en varios directorios .lproj, y al abrirlos dentro de Interface Builder, la jerarquía de clases puede eliminarse espontáneamente de algunos y agregarse a otros, o dejarse solo en algunos. Esto causa mucho ruido git diff
, pero en realidad no interrumpe ninguna funcionalidad. A menudo agregaremos selectivamente los cambios reales que realizamos en el índice de git, los confirmaremos y luego simplemente descartaremos lo espontáneo y sin sentido.<classes>
cambios Esto es para mantener compromisos pequeños y agradables, como deberían ser. Eventualmente, sin embargo, se vuelve demasiado molesto ya que Xcode sigue volviendo a hacer los cambios, y alguien simplemente los confirma junto con otras cosas ... lo cual está bien hasta que el Xcode de otra persona decida querer volver a cambiarlos sin ningún problema. razón aparente. (Nuestra historia de compromiso tiene muchas palabrotas sobre esto).
¿Alguien más está viendo este comportamiento? ¿Es esto un error de Xcode o un problema de configuración en uno o más de nuestros Mac para desarrolladores? Hemos visto un comportamiento similar al colaborar con archivos XIB, pero los guiones gráficos parecen más susceptibles a esto.
fuente
Respuestas:
Esto no es un error, es una consecuencia de cómo Xcode procesa los archivos del guión gráfico. Estoy escribiendo un programa de diferencias y fusión para archivos de guiones gráficos (enlace GitHub) y he pasado horas analizando la lógica de los archivos de guiones gráficos y cómo Xcode los procesa. Esto es lo que descubrí:
¿Por qué ocurren cambios extraños en los archivos del guión gráfico? Xcode usa la API NSXML para analizar archivos de guiones gráficos en una
NSSet
estructura de árbol lógico basada en algo . Cuando Xcode necesita escribir cambios, crea unaNSXMLDocument
estructura basada en el árbol lógico, borra el archivo del guión gráfico y llamaXMLDataWithOptions:
para volver a llenar el archivo. Debido a que los conjuntos no conservan el orden de sus elementos, incluso la más mínima modificación podría cambiar todo el archivo XML del guión gráfico.¿Por qué la etiqueta de clase desaparece o reaparece al azar? La
<class>
sección no es más que un caché interno de Xcode. Xcode lo usa para almacenar en caché información sobre las clases. El caché cambia a menudo. Los elementos se agregan cuando los.h/.m
archivos de clase se abren y se eliminan cuando Xcode sospecha que están desactualizados (al menos los códigos X más antiguos se comportan así). Cuando guarda el guión gráfico, se descarga la versión actual de la memoria caché, por lo que la<class>
sección a menudo cambia o incluso desaparece.No he realizado ingeniería inversa de Xcode; Hice estas observaciones experimentando con Xcode y archivos de guión gráfico. Sin embargo, estoy casi 100% seguro de que funciona de esta manera.
Conclusiones :
MyController1
controlador de vista en un documento de guión gráfico. Abra el archivo del guión gráfico y encuentre algo como esto<viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>
. Puede confirmar de forma segura solo los cambios en esta sección e ignorar todo lo demás. Si cambiaste segues o restricciones, también confirma todo lo que tiene“ory-XY-OBM”
dentro. ¡Sencillo!fuente
Este es un error en XCode 4.5+, espero que se solucione, y sí, es un PITA.
Aquí está el error completo en Apple
¿Cómo evitar las ediciones gratuitas de Xcode en los archivos del guión gráfico?
fuente
Este problema puede mitigarse un poco mediante el uso extremadamente juicioso de
git add -p
cualquiera de los archivos generados por Xcode, incluidos los guiones gráficos, los XIB, los modelos de datos básicos y los archivos de proyecto, todos los cuales sufren modificaciones transitorias similares que no tienen impacto en la interfaz / modelo real / proyecto.Los cambios basura más comunes que he visto en los guiones gráficos son los números de versión del sistema (como usted menciona) y la constante adición y eliminación de la
<classes>
sección, cuya omisión que nunca he visto causa problemas. Para XIB, es la adición y eliminación de<reference key="NSWindow"/>
, que ni siquiera es una clase en Cocoa Touch. Simplemente guau.Piense en ello como el mar: hay marea alta y baja. Deja que te lave.
Ahh Eso es.
Puede ignorar estas modificaciones al organizar sus cambios, restablecer los cambios no deseados y realizar una confirmación limpia.
La única ventaja que he visto con los guiones gráficos sobre XIB desde un punto de vista técnico es que Apple aún no ha neutralizado FileMerge para negarse a fusionar guiones gráficos en conflicto. (FileMerge solía ser capaz de fusionar XIB, pero las versiones más nuevas lo rompieron. ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡Presente muchos errores sobre todos estos problemas en http://bugreporter.apple.com/ ! Y no olvides crear entradas en OpenRadar .
fuente
Lanzando otra respuesta aquí porque esta situación ha mejorado mucho. El XML para el archivo XIB que representa el StoryBoard se ha simplificado enormemente.
También he mordido la bala recientemente y comencé a usar la interfaz en Xcode to Source Control. He estado en la línea de comandos durante años y estoy feliz allí, pero la interfaz es agradable y te permite dividir los commits, lo cual es realmente importante si utilizas un sistema de tickets que se vincula a los commits.
De todos modos, me di cuenta hoy de que había un cambio en el guión gráfico y la diferencia incorporada me mostró que era un atributo único en la etiqueta del documento (systemVersion). Así que no es gran cosa.
He leído artículos donde la gente dice que los SB fueron prohibidos en sus equipos debido a problemas de fusión. Locura total. Son tan asombrosos, especialmente ahora que tienen una distribución automática inteligente incorporada, realmente te estás perdiendo si no los estás usando.
fuente
Es útil saber por qué está ocurriendo esta locura, pero para aquellos que creen en mantener sus proyectos libres de advertencias y que solo quieren un proceso rápido y sucio para que sus proyectos vuelvan a un estado saludable:
No cometas nada hasta que se te indique explícitamente.
Abra Xcode y cree un nuevo guión gráfico (Comando + N> iOS> Interfaz de usuario> Guión gráfico). Asumiré que lo llamas el nombre predeterminado de
Storyboard.storyboard
.Abra el guión gráfico que Xcode ha violado. Asumiré que esto es
Base.lproj/Main.storyboard
.Seleccione y copie todo en el guión gráfico (Comando + A y luego Comando + C).
Abierto
Storyboard.storyboard
.Copia y pega todo en
Storyboard.storyboard
.Cierra Xcode.
Abra una terminal y cambie los directorios a su repositorio.
Reemplace
Main.storyboard
conStoryboard.storyboard
(mv Storyboard.storyboard Base.lproj/Main.storyboard
).git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."
Haga caso omiso de los cambios a
project.pbxproj
viagit checkout -- project.pbxproj
. Si tienegit diff
el archivo, verá que acaba de agregar información sobre nuestro guión gráfico temporal (que ya no existe).Abra Xcode de nuevo y vea que las advertencias han desaparecido.
Respirar.
fuente
Trabajar en el mismo guión gráfico no es un problema. Pero trabajar en el mismo controlador de vista que crea conflictos en pull / merge es aterrador. Realmente no podemos evitar que funcione en el mismo controlador de vista para un equipo grande.
Lo bueno es que la mayoría de las veces podemos solucionar los mismos conflictos de viewcontroller si entendemos la estructura xml. Nunca fallé en combinarlos mientras trabajaba en equipo. Supongamos que está trabajando con un controlador de vista. Su vista está en blanco actualmente. Por favor, eche un vistazo a la estructura xml de viewcontroller desde la opción de código fuente.
Storyboard está limitado por la etiqueta de tipo de documento. Todo en el guión gráfico contiene en la escena sceneID = tag. La etiqueta de escena contiene todos los controladores de vista. Eso es lo básico.
Ahora agregamos un UILabel y un UIButton en la vista. Establezca también la distribución automática de los elementos. Ahora se ve así:
Agregar un nivel / botón al controlador de vista agregó un código nuevo dentro de la etiqueta de subvista de la vista. Lo mismo se aplicará para agregar elementos adicionales o cualquier cambio en la interfaz de usuario. Verifique cuidadosamente la estructura de la etiqueta, que es realmente importante para solucionar cualquier conflicto.
Ahora agregamos otro viewcontroller en el nombre del guión gráfico Homeviewcontroller. Agregar un nuevo controlador de vista significa que agrega una nueva escena debajo de la etiqueta de escenas. Mira este:
En este punto, cambiaremos la estructura al azar y observaremos los problemas / advertencias. Cambiamos la etiqueta final de la etiqueta viewcontroller y guardamos el archivo. Ahora ejecútelo y mire la advertencia. El error dice que la etiqueta final no es correcta, que se creó a partir de la línea 23. En la línea 23, vemos que se establecen restricciones de etiqueta sin etiqueta final. Ese es el problema. Ahora ponemos la etiqueta final y compilamos el proyecto. Después de configurar la etiqueta final, podemos ver el guión gráfico con éxito.
Cuando enfrente cualquier advertencia de conflictos, compare con su fuente anterior y la fuente de cambios. Eliminamos el código antiguo / redundante, conservamos el código nuevo con la etiqueta adecuada de inicio a fin y arreglamos las cosas.
[Nota: actualizaré la respuesta con algunos casos de prueba más cuando llegue el momento]
fuente