Objective-C: la esencia del lenguaje y su lugar en el desarrollo iOS

Autor: IT Sectr Publicado: 2026-02-09 Tiempo de lectura: 8 min

Objective-C es un lenguaje de programación con despacho dinámico de mensajes, creado por Brad Cox en la década de 1980. Apple eligió Objective-C como lenguaje principal para NeXTSTEP y más tarde para el SDK de iOS. Programming With Objective-C — una introducción a la sintaxis de mensajes y la gestión de memoria.

Puntos clave

  • Objective-C — un superconjunto estricto de C con sintaxis de mensajes entre corchetes y un runtime dinámico
  • Message passing — llamadas a métodos mediante [object selector:argument] con búsqueda dinámica de implementación a través de objc_msgSend
  • Categories — mecanismo para añadir métodos a clases existentes sin herencia y sin acceso al código fuente
  • Blocks — funciones anónimas con cierres, predecesor de los closures de Swift
  • ARC vs MRC — recuento automático y manual de referencias para la gestión de memoria

¿Qué es Objective-C?

Objective-C es un lenguaje de programación que extiende C con capacidades de programación orientada a objetos al estilo Smalltalk. El código Objective-C se compila mediante LLVM o GCC en código máquina nativo, manteniendo total compatibilidad hacia atrás con C — cualquier código C es válido en Objective-C.

Apple adquirió NeXT (junto con Objective-C) en 1997. El lenguaje se convirtió en la base de Cocoa y Cocoa Touch — los frameworks para macOS e iOS. Desde 2014, Apple promueve Swift como reemplazo, pero Objective-C sigue siendo críticamente importante para proyectos heredados y algunos frameworks del sistema. Según Apple (WWDC 2024), alrededor del 35% de las aplicaciones en la App Store aún contienen código Objective-C.

La característica clave es el runtime dinámico. A diferencia de Swift, donde las llamadas a métodos se resuelven en tiempo de compilación, Objective-C envía mensajes en tiempo de ejecución a través de la función objc_msgSend. Esto permite sobrescribir métodos sobre la marcha (method swizzling), añadir clases dinámicamente y usar forward invocation para selectores inexistentes.

Sintaxis: C + extensión orientada a objetos

Cualquier código C es válido en Objective-C. La extensión orientada a objetos añade clases (@interface/@implementation), categorías, protocolos (@protocol) y tipado dinámico (id). Los archivos tienen extensiones .m (implementación) y .h (encabezados).

Sintaxis de mensajes y despacho dinámico

La sintaxis de mensajes es la principal diferencia entre Objective-C y los lenguajes similares a C. En lugar de object.method(argument), se utiliza [object method:argument]. Cada mensaje pasa a través de objc_msgSend, que busca dinámicamente la implementación del método en el runtime.

objective-c
// Sintaxis de mensajes con parámetros nombrados
NSString *greeting = [NSString stringWithFormat:@"Hello, %@", name];

// Mensajes anidados
NSArray *sortedArray = [[array sortedArrayUsingSelector:@selector(compare:)] copy];

// Verificación de tipo mediante introspection
if ([object isKindOfClass:[UIView class]]) {
    UIView *view = (UIView *)object;
    view.backgroundColor = [UIColor redColor];
}

El despacho dinámico permite sobrescribir métodos en tiempo de ejecución (method swizzling) — una técnica potente pero peligrosa. Por ejemplo, frameworks como AFNetworking y Aspects utilizan swizzling para interceptar llamadas de URLSession. Apple advierte: el swizzling puede dañar los frameworks del sistema si se usa incorrectamente.

Categorías y extensiones de clase

Las Categorías son una característica única de Objective-C que permite añadir métodos a clases existentes (incluyendo clases del sistema como NSString y UIView) sin herencia y sin acceso al código fuente. Las categorías se declaran mediante @interface ClassName (CategoryName).

objective-c
// Archivo UIColor+Hex.h — categoría para UIColor
@interface UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex;
@end

// Archivo UIColor+Hex.m — implementación
@implementation UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex {
    CGFloat r = ((hex >> 16) & 0xFF) / 255.0;
    CGFloat g = ((hex >> 8) & 0xFF) / 255.0;
    CGFloat b = (hex & 0xFF) / 255.0;
    return [self colorWithRed:r green:g blue:b alpha:1.0];
}
@end

Las Extensiones (Class Extension) son un tipo especial de categoría declarada en un archivo .m sin nombre: @interface ClassName (). A diferencia de las categorías, las extensiones pueden añadir no solo métodos sino también ivar (variables de instancia) y propiedades. Las extensiones se utilizan para ocultar la API interna de los módulos externos.

Bloques (Blocks) — funciones anónimas con cierres

Los Bloques son funciones anónimas en Objective-C que capturan variables del ámbito externo. Sintaxis de bloques: ^(int x) { return x * 2; }. Los bloques se utilizan en UIKit para manejadores de callback, en Grand Central Dispatch para tareas asíncronas y en colecciones NSArray/NSDictionary para operaciones funcionales.

objective-c
// Declaración de tipo de bloque
typedef void (^CompletionBlock)(BOOL success, NSError *error);

// Bloque como parámetro
- (void)fetchDataWithCompletion:(CompletionBlock)completion {
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL result = [weakSelf processData];
        if (completion) {
            completion(result, nil);
        }
    });
}

La gestión de memoria en los bloques es críticamente importante. Los bloques capturan self con una referencia fuerte, creando un retain cycle cuando se usan directamente. La solución es __weak typeof(self) weakSelf = self, seguida de una verificación dentro del bloque. Este problema está completamente resuelto en Swift mediante capture lists [weak self].

ARC y MRC: gestión de memoria

Objective-C evolucionó de MRC (Manual Reference Counting) a ARC (Automatic Reference Counting). En MRC, el desarrollador llamaba manualmente a retain (incrementar contador), release (decrementar) y autorelease (liberación diferida). Los errores en estas llamadas provocaban fugas de memoria o crashes debido a punteros colgantes.

OperaciónMRCARC
Creación de objeto[[Object alloc] init][[Object alloc] init]
Retención de referencia[object retain]Automáticamente
Liberación[object release]Automáticamente
Autoliberación[object autorelease]Automáticamente (no requerido)
Referencia débil__weak no existía__weak (nil automático)

ARC se introdujo en Xcode 4.2 y LLVM 3.0 (2011). El compilador inserta automáticamente retain/release en tiempo de compilación analizando el ciclo de vida de los objetos. ARC no es recolección de basura — es análisis estático con inserciones automáticas. ARC de Objective-C es compatible con ARC de Swift: ambos usan el mismo sistema de recuento de referencias a nivel de runtime.

Interoperabilidad con Swift mediante Bridging Header

El uso conjunto de Objective-C y Swift en un mismo proyecto es una práctica común para proyectos heredados. Apple proporciona el Bridging Header — un archivo generado automáticamente a través del cual Swift ve las clases de Objective-C, y Objective-C ve las clases de Swift que heredan de NSObject.

objective-c
// ProjectName-Bridging-Header.h
// Swift ve estos encabezados automáticamente
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"

La migración de Objective-C a Swift es un proceso gradual. Los archivos nuevos se escriben en Swift, los antiguos se refactorizan gradualmente. El Bridging Header se genera automáticamente al añadir el primer archivo Swift a un proyecto Objective-C. Para la visibilidad inversa (ObjC → Swift), Xcode genera un archivo <ProjectName>-Swift.h que contiene declaraciones @interface para las clases Swift marcadas con @objc.

swift
// Clase Swift visible desde Objective-C
@objc class SwiftRouter: NSObject {
    @objc func navigateToProfile(userId: Int) {
        // implementación
    }
}

Limitaciones: los tipos valor de Swift (struct, enum) no son visibles directamente desde Objective-C — deben envolverse en una clase con @objc. Los genéricos de Swift tienen accesibilidad limitada desde Objective-C. El enfoque recomendado es escribir código nuevo en Swift y refactorizar el código Objective-C existente solo al cambiar la funcionalidad correspondiente.

Runtime y Method Swizzling en Objective-C

La principal ventaja de Objective-C sobre Swift es el acceso completo al runtime. El method swizzling, que reemplaza implementaciones de métodos en tiempo de ejecución, permite sobrescribir métodos del sistema sin herencia. Bibliotecas como Aspects y JRSwizzle utilizan esta capacidad para AOP (programación orientada a aspectos) — monitoreo, analítica y registro.

Forward invocation es otra característica del runtime: si un objeto no responde a un selector, el sistema llama a forwardInvocation:, permitiendo reenviar el mensaje a otro objeto. Esta es la base del patrón Proxy en Objective-C (NSProxy), utilizado para inicialización perezosa y objetos distribuidos.

Apple recomienda minimizar el uso de trucos del runtime en código nuevo, prefiriendo el tipado estático de Swift. Sin embargo, en proyectos heredados, el conocimiento de objc_msgSend, method_exchangeImplementations y objc_getAssociatedObject es necesario para mantener la base de código existente.

Propiedades y Key-Value Observing

Objective-C soporta propiedades como azúcar sintáctico sobre ivar con getters/setters. Los modificadores atomic/nonatomic, strong/weak/copy, readonly/readwrite y assign/retain determinan el comportamiento de memoria y la seguridad de hilos. Key-Value Observing (KVO) es un mecanismo para observar cambios en propiedades, integrado en el runtime: cualquier objeto puede suscribirse a cambios en las propiedades de otro objeto mediante addObserver.

Preguntas frecuentes

¿Qué es la sintaxis de mensajes en Objective-C?

Una llamada a método se ve como [object selector:argument]. El mensaje pasa a través de objc_msgSend, que encuentra dinámicamente la implementación en el runtime. Un selector es un nombre de método (@selector(methodName)), no un puntero a función. Esto permite swizzling y forward invocation.

¿En qué se diferencian las Categorías de las Extensiones?

Una Categoría (@interface ClassName (Name)) añade métodos a cualquier clase (incluidas las del sistema) sin herencia. Una Extensión (@interface ClassName ()) se declara en un archivo .m y puede añadir propiedades e ivars. Una Categoría no puede añadir ivars, pero una Extensión sí.

¿Qué son los Bloques (Blocks) en Objective-C?

Los Bloques son funciones anónimas con sintaxis ^(parámetros) { cuerpo }, que capturan variables del contexto. Son análogos a las lambdas en C++ y a los closures en Swift. Requieren __weak para prevenir retain cycles al capturar self. Se usan en UIKit, GCD y Foundation.

¿Cuál es la diferencia entre ARC y MRC?

MRC es recuento manual de referencias: el programador llama a retain, release, autorelease. ARC es automático: el compilador inserta retain/release basándose en análisis estático. ARC no es GC — los objetos se liberan inmediatamente cuando el contador llega a cero. ARC soporta los modificadores __weak y __strong.

¿Se pueden usar Objective-C y Swift en el mismo proyecto?

Sí, mediante un Bridging Header. Swift ve Objective-C a través de este encabezado, Objective-C ve Swift mediante <ProjectName>-Swift.h. Las clases Swift deben heredar de NSObject y marcarse con @objc. Los struct y enum de Swift no son visibles directamente para Objective-C.

Resumen

  • Objective-C — un superconjunto estricto de C con runtime dinámico y sintaxis de mensajes para Cocoa/Cocoa Touch
  • Message passing — llamadas mediante [object method] con despacho dinámico a través de objc_msgSend y capacidad de swizzling
  • Categorías — adición de métodos a clases existentes sin herencia, incluyendo clases del sistema de Apple
  • Bloques — funciones anónimas con cierres, que requieren __weak para prevenir retain cycles
  • ARC vs MRC — evolución desde retain/release manual hasta recuento automático de referencias mediante el compilador
  • Bridging Header — mecanismo para que Swift y Objective-C trabajen juntos en un mismo proyecto para migración gradual
  • Importancia heredada — alrededor del 35% de las aplicaciones de la App Store contienen código Objective-C que requiere mantenimiento

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también