iphone - secretos - como hago para que nadie me encuentre en facebook 2017
Características ocultas de Objective-C (8)
Posando
Objective-C permite que una clase reemplace por completo a otra clase dentro de una aplicación. Se dice que la clase de reemplazo "representa como" la clase objetivo. Todos los mensajes enviados a la clase objetivo son recibidos por la clase que posa. Existen algunas restricciones sobre las clases que pueden plantear:
- Una clase solo puede posar como una de sus superclases directas o indirectas
- La clase de presentación no debe definir ninguna variable de instancia nueva que esté ausente de la clase de destino (aunque puede definir o anular métodos).
- No se deben haber enviado mensajes a la clase objetivo antes de posar.
Posar, de manera similar a las categorías, permite aumentar las clases existentes a nivel mundial . Posing permite dos características ausentes de las categorías:
- Una clase posante puede llamar a los métodos anulados a través de super, incorporando así la implementación de la clase objetivo.
- Una clase posante puede anular los métodos definidos en categorías.
Un ejemplo:
@interface CustomNSApplication : NSApplication
@end
@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu
{
// do something with menu
}
@end
class_poseAs ([CustomNSApplication class], [NSApplication class]);
Esto intercepta cada invocación de setMainMenu a NSApplication.
Objective-C tiene un uso más amplio debido a su uso por parte de Apple para el desarrollo de Mac OS X y iPhone. ¿Cuáles son algunas de tus características favoritas "ocultas" del lenguaje Objective-C?
- Una característica por respuesta.
- Dé un ejemplo y una breve descripción de la característica, no solo un enlace a la documentación.
- Etiquete la función usando un título como primera línea.
#include <Foundation/Debug.h>
Muchas herramientas para tratar de rastrear fugas de memoria, transacciones prematuras y más en ese archivo de encabezado.
Referencia de tiempo de ejecución de Objective-C
Es fácil olvidar que el azúcar sintáctico de Objective-C se convierte en llamadas normales a la función C que son el Object-C Runtime. Es probable que nunca necesite profundizar y usar nada en el tiempo de ejecución. Es por eso que consideraría esto una ''característica oculta''.
Déjame dar una manera en que uno podría usar el sistema de tiempo de ejecución.
Digamos que alguien está diseñando una API de marco externo que será utilizada por terceros. Y que alguien diseña una clase en el marco que represente abstractamente un paquete de datos, lo llamaremos MLAbstractDataPacket
. Ahora le corresponde a la aplicación que está vinculando en el marco a la subclase MLAbstractDataPacket
y define los paquetes de datos de la subclase. Cada subclase debe anular el método +(BOOL)isMyKindOfDataPacket:(NSData *)data
.
Con esa información en mente ...
Sería bueno si MLAbstractDataPacket
proporcionara un método de conveniencia que devolviera la clase inicializada correcta para un paquete de datos que viene en forma +(id)initWithDataPacket:(NSData *)data
.
Solo hay un problema aquí. La superclase no conoce ninguna de sus subclases. De modo que aquí podría usar el método de ejecución objc_getClassList()
junto con objc_getSuperclass()
para buscar las clases que son subclases de MLAbstractDataPacket. Una vez que tenga una lista de subclases, puede probar +isMyKindOfDataPacket:
en cada una de ellas hasta encontrarla o no encontrarla.
La información de referencia sobre esto se puede encontrar en http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html .
Me gusta el método detallado que nombra como [myArray writeToFile:myPath atomically:YES]
, donde cada argumento tiene una etiqueta.
Categorías
Usando Categorías, puede agregar métodos a las clases integradas sin subclases. Referencia completa
Es agradable agregar métodos de conveniencia a las clases comúnmente utilizadas, como NSString o NSData.
Reenvío de objetos / Método faltante
Cuando se envía un objeto a un mensaje para el que no tiene ningún método, el sistema de tiempo de ejecución le da otra oportunidad de manejar la llamada antes de darse por vencido. Si el objeto admite un método -forward ::, el tiempo de ejecución llama a este método, pasándole información sobre la llamada no controlada. El valor de retorno de la llamada reenviada se propaga nuevamente a la persona que llama original del método.
-(retval_t)forward:(SEL)sel :(arglist_t)args {
if ([myDelegate respondsTo:sel])
return [myDelegate performv:sel :args]
else
return [super forward:sel :args];
}
Contenido de Objective-C Pocket Reference
Esto es muy poderoso y se utiliza mucho en la comunidad de Ruby para los diversos DSL y rieles, etc. Originado en Smalltalk que influyó tanto en Objective-C como en Ruby.
Conmutación ISA
¿Necesita anular todos los comportamientos de un objeto? En realidad, puede cambiar la clase de un objeto activo con una sola línea de código:
obj->isa = [NewClass class];
Esto solo cambia la clase que recibe llamadas de método para ese objeto; no cambia el diseño del objeto en la memoria. Por lo tanto, esto solo es realmente útil cuando tienes un conjunto de clases con los mismos ivars (o uno con un subconjunto de los demás) y quieres cambiar entre ellos.
Una parte del código que he escrito usa esto para la carga diferida: asigna un objeto de clase A
, llena un par de ivars críticos (en este caso, principalmente un número de registro) y conmuta el puntero isa
para apuntar a LazyA
. Cuando se llama a cualquier método que no sea muy pequeño, como release
y retain
, LazyA
carga todos los datos del disco, termina de rellenar los ivars, cambia el puntero isa
a A
y reenvía la llamada a la clase real.
Método Swizzling
Básicamente, en tiempo de ejecución puede intercambiar una implementación de un método con otro.
Aquí hay una explicación con código.
Un caso de uso inteligente es la carga diferida de un recurso compartido: por lo general, se implementa un método de sharedFoo
adquiriendo un bloqueo, creando el foo
si es necesario, obteniendo su dirección, liberando el bloqueo, y luego devolviendo el foo
. Esto asegura que el foo
solo se crea una vez, pero cada acceso posterior pierde tiempo con un bloqueo que ya no se necesita.
Con el método swizzling, puede hacer lo mismo que antes, excepto una vez que se haya creado el foo
, use swizzling para cambiar la implementación inicial de sharedFoo
por un segundo que no haga chequeos y simplemente devuelva el foo
que ahora sabemos que ha sido creado !
Por supuesto, el método Swizzling puede meterlo en problemas, y puede haber situaciones en las que el ejemplo anterior sea una mala idea, pero bueno ... es por eso que es una función oculta .