Los objetos asociados (también conocidos como referencias asociativas) son una característica extremadamente útil pero algo oscura del tiempo de ejecución Objective-C de Apple (por lo que técnicamente no se trata de una “característica Objective-C”, sino una característica del tiempo de ejecución de Apple). Está disponible en Mac OS X 10.6+ y iOS 3.1+. y usa las funciones
objc_getAssociatedObject()
y objc_setAssociatedObject
para obtenerlos y configurarlos, respectivamente.
Básicamente, le permite “adjuntar” arbitrariamente un objeto a otro objeto, como si fuera una variable de instancia. Al adjuntar, puede especificar si el objeto secundario debe ser retenido, copiado o no por el padre; si se retiene, se liberará cuando el objeto principal se desasigne (como lo que se suele hacer con las variables de instancia). Esto es útil para almacenar “datos de usuario personalizados” en controles como vistas de alertas, hojas de acciones, botones, etc., que invocan un método delegado o un selector de destino en una acción.
Considere sin objetos asociados, ¿cómo almacenaría los “datos del usuario” para que una vez que se llame a su selector de acción, pueda acceder a los “datos del usuario”? Aquí hay algunas opciones:
- ¿Cómo es ser un desarrollador de iOS en Google?
- ¿Qué hay de malo en la plataforma de computación móvil y por qué aún no podemos reemplazar la computación de PC con ella?
- ¿Cómo se compara iOS 10 con versiones anteriores de iOS?
- ¿Cuáles son las principales diferencias entre el iPhone 4, iPhone 4S y el iPhone 5?
- ¿Hay alguna manera de usar Android e iOS en un iPhone 6?
- Almacénelo como una variable de instancia dentro de la clase “padre” que sirve como delegado; sin embargo, esto solo funciona para un número fijo de controles. Si está creando dinámicamente un número ilimitado de botones, por ejemplo, esto no funcionará.
- Si el control en cuestión es una UIView, use la propiedad “etiqueta”. Sin embargo, esto solo puede almacenar un número entero, no datos complejos arbitrariamente.
- Subclase el control en cuestión y agregue una variable de instancia a la subclase. Esto funciona. Sin embargo, crear una nueva clase es detallado y molesto; y esto solo funcionará si está creando el control en cuestión, y no funcionará si obtiene el objeto creado por otra persona y desea adjuntarle datos.
- Mantenga un diccionario desde la dirección del control hasta los datos del usuario. El problema con esto es que no sabrá cuándo el control ya no es necesario (desasignado), por lo que tendrá que seguir reteniendo los datos del usuario, causando una pérdida de memoria si los controles se crean continuamente.
- Haga que el objeto de datos del usuario sea el delegado u objetivo del control y que sea de una clase personalizada con métodos para manejar la acción de delegado u objetivo. Sin embargo, esto no funcionará, porque los controles no retienen a sus delegados u objetivos, por lo que esto se bloqueará (si nadie retiene al delegado y se desasigna y luego se le envía un mensaje) o debe retenerse en algún lugar indefinidamente , causando una pérdida de memoria.
Los objetos asociados resuelven esto de una manera simple. Podemos configurar el objeto asociado para que se retenga, de modo que no tengamos que preocuparnos por retenerlo por separado, y se liberará automáticamente cuando el control ya no exista. Los objetos asociados también se usan para agregar una categoría de “interfaz de bloque” a las clases existentes basadas en delegados, almacenando el bloque como un objeto asociado.
Desafortunadamente, usar objetos asociados es un poco extraño. Se siente hacky tener que importar “objc / runtime.h” y luego usar funciones C con nombres que comienzan con “objc_”, como si de alguna manera estuvieras hackeando las partes internas de Objective-C. No hay una interfaz conveniente como método de NSObject o algo así. Además, las funciones de los objetos asociados requieren que use una “clave”, que no es una cadena, sino un puntero. Como resultado, la forma estándar de usarlo es crear una variable ficticia no utilizada y usar su dirección como clave (para asegurarse de que no entrará en conflicto con nada más). De nuevo, muy raro.