Objective-C: у чему је суштина језика и његово место у iOS развоју

Аутор: IT Sectr Објављено: 2026-02-09 Време читања: 8 мин

Objective-C — програмски језик са динамичким слањем порука, створен од Бреда Кокса 1980-их. Apple је изабрао Objective-C као главни језик за NeXTSTEP, а затим и за iOS SDK. Programming With Objective-C — увод у синтаксу порука и управљање меморијом.

Главно

  • Objective-C — строги надскуп C-а са синтаксом порука у угластим заградама и динамичким runtime-ом
  • Message passing — позив методе кроз [object selector:argument] са динамичким тражењем имплементације кроз objc_msgSend
  • Categories — механизам додавања метода постојећим класама без наслеђивања и без приступа изворном коду
  • Blocks — анонимне функције са затварањем, претходник Swift closures-а
  • ARC vs MRC — аутоматско и ручно бројање референци за управљање меморијом

Шта је Objective-C?

Objective-C — програмски језик који проширује C могућностима објектно-оријентисаног програмирања у стилу Smalltalk-а. Код на Objective-C-у се компилира кроз LLVM или GCC у нативни машински код, чувајући потпуну уназад компатибилност са C-ом — било који C код је исправан у Objective-C-у.

Apple је преузео NeXT (заједно са Objective-C-ом) 1997. године. Језик је постао основа Cocoa и Cocoa Touch — оквира за macOS и iOS. Од 2014. Apple промовише Swift као замену, али Objective-C остаје критично важан за легаси пројекте и неке системске оквире. Према Apple-у (WWDC 2024), око 35% апликација у App Store-у још увек садржи Objective-C код.

Кључна карактеристика — динамички runtime. За разлику од Swift-а, где се позиви метода решавају у фази компилације, Objective-C шаље поруке током извршавања кроз функцију objc_msgSend. То омогућава преиначавање метода у лету (method swizzling), динамичко додавање класа и коришћење forward invocation-а за непостојеће селекторе.

Синтакса: C + објектна надградња

Било који C код је исправан у Objective-C-у. Објектна надградња додаје класе (@interface/@implementation), категорије, протоколе (@protocol) и динамичко типизовање (id). Датотеке имају екстензије .m (имплементација) и .h (заглавља).

Синтакса порука и динамичка диспечеризација

Синтакса порука — главна разлика Objective-C-а од C-сличних језика. Уместо object.method(argument) користи се [object method:argument]. Свака порука пролази кроз objc_msgSend, који динамички тражи имплементацију метода у runtime-у.

objective-c
// Синтакса порука са именованим параметрима
NSString *greeting = [NSString stringWithFormat:@"Hello, %@", name];

// Угњеждене поруке
NSArray *sortedArray = [[array sortedArrayUsingSelector:@selector(compare:)] copy];

// Провера типа кроз интроспекцију
if ([object isKindOfClass:[UIView class]]) {
    UIView *view = (UIView *)object;
    view.backgroundColor = [UIColor redColor];
}

Dynamic dispatch омогућава преиначавање метода у runtime-у (method swizzling) — моћна, али опасна техника. На пример, оквири попут AFNetworking-а и Aspects-а користе swizzling за пресретање позива URLSession-а. Apple упозорава: swizzling може пореметити рад системских оквира ако се неправилно користи.

Категорије и проширења класа

Categories — јединствена могућност Objective-C-а да додаје методе постојећим класама (укључујући системске, попут NSString и UIView) без наслеђивања и без приступа изворном коду. Категорије се декларишу кроз @interface ClassName (CategoryName).

objective-c
// Датотека UIColor+Hex.h — категорија за UIColor
@interface UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex;
@end

// Датотека UIColor+Hex.m — имплементација
@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

Extensions (Class Extension) — посебна врста категорије, декларисана у .m датотеци без имена: @interface ClassName (). За разлику од категорија, extensions могу додавати не само методе, већ и ivar (инстанцне варијабле) и property. Extensions се користе за скривање унутрашњег API-ја од спољашњих модула.

Блокови — анонимне функције са затварањем

Blocks — анонимне функције у Objective-C-у, које хватају променљиве из спољашњег опсега видљивости. Синтакса блокова: ^(int x) { return x * 2; }. Blocks се користе у UIKit-у за callback-обраднике, у Grand Central Dispatch-у за асинхроне задатке и у колекцијама NSArray/NSDictionary за функционалне операције.

objective-c
// Декларација типа блока
typedef void (^CompletionBlock)(BOOL success, NSError *error);

// Блок као параметар
- (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);
        }
    });
}

Управљање меморијом у блоковима је критично. Блокови хватају self јаком референцом, што ствара retain cycle при директном коришћењу. Решење — __weak typeof(self) weakSelf = self, са накнадном провером унутар блока. Овај проблем је потпуно решен у Swift-у кроз листе за хватање [weak self].

ARC и MRC: управљање меморијом

Objective-C је прешао пут од MRC (Manual Reference Counting) до ARC (Automatic Reference Counting). У MRC-у програмер је ручно позивао retain (повећање бројача), release (смањење) и autorelease (одложени release). Грешке у овим позивима доводиле су до цурења меморије или падова због dangling pointers-а.

ОперацијаMRCARC
Креирање објекта[[Object alloc] init][[Object alloc] init]
Држање референце[object retain]Аутоматски
Ослобађање[object release]Аутоматски
Аутоослобађање[object autorelease]Аутоматски (није потребно)
Weak референца__weak није постојао__weak (аутоматски nil)

ARC је представљен у Xcode 4.2 и LLVM 3.0 (2011). Компилатор аутоматски убацује retain/release у фази компилације, анализирајући животни век објеката. ARC није сакупљање смећа (garbage collection) — то је статичка анализа са аутоматским убацивањем. Objective-C ARC је компатибилан са Swift ARC: оба користе исти систем бројања референци на нивоу runtime-а.

Интеракција са Swift-ом кроз Bridging Header

Заједничко коришћење Objective-C и Swift-а у једном пројекту — уобичајена пракса за легаси пројекте. Apple обезбеђује Bridging Header — аутоматски генерисану датотеку кроз коју Swift види Objective-C класе, а Objective-C види Swift класе наслеђене од NSObject-а.

objective-c
// ProjectName-Bridging-Header.h
// Swift види ова заглавља аутоматски
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"

Миграција са Objective-C на Swift — фазни процес. Нове датотеке се пишу у Swift-у, старе се постепено рефакторишу. Bridging Header се аутоматски генерише при додавању прве Swift датотеке у Objective-C пројекат. За обрнуту видљивост (ObjC → Swift), Xcode генерише датотеку -Swift.h која садржи @interface за Swift класе означене са @objc.

swift
// Swift класа видљива из Objective-C-а
@objc class SwiftRouter: NSObject {
    @objc func navigateToProfile(userId: Int) {
        // имплементација
    }
}

Ограничења: Swift value-типови (struct, enum) нису видљиви из Objective-C-а директно — морају се умотати у class са @objc. Generics у Swift-у су ограничено доступни из Objective-C-а. Препоручени приступ — пишите нови код у Swift-у, а постојећи Objective-C код рефакторишите само при промени одговарајуће функционалности.

Runtime и method swizzling у Objective-C-у

Главна предност Objective-C-а над Swift-ом — пун приступ runtime-у. Method swizzling, замена имплементације метода током извршавања, омогућава преиначавање системских метода без наслеђивања. Библиотеке попут Aspects-а и JRSwizzle-а користе ову могућност за AOP (аспектно-оријентисано програмирање) — праћење, аналитику и логирање.

Forward invocation — још једна runtime могућност: ако објекат не одговара на селектор, систем позива forwardInvocation:, омогућавајући преусмеравање поруке другом објекту. То је основа Proxy узорка у Objective-C-у (NSProxy), који се користи за одложену иницијализацију и дистрибуиране објекте.

Apple препоручује минимизирање коришћења runtime трикова у новом коду, дајући предност статичком типизовању Swift-а. Међутим, у легаси пројектима познавање objc_msgSend, method_exchangeImplementations и objc_getAssociatedObject је неопходно за одржавање постојеће базе кода.

Property и Key-Value Observing

Objective-C подржава property као синтаксни шећер над ivar-ом са getter-има/setter-има. Модификатори atomic/nonatomic, strong/weak/copy, readonly/readwrite и assign/retain одређују понашање меморије и безбедност нити. Key-Value Observing (KVO) — механизам посматрања промена својстава уграђен у runtime: било који објекат може да се претплати на промене својстава другог објекта кроз addObserver.

Често постављана питања

Шта је синтакса порука у Objective-C-у?

Позив методе изгледа као [object selector:argument]. Порука пролази кроз objc_msgSend, који динамички проналази имплементацију у runtime-у. Селектор је име методе (@selector(methodName)), а не показивач на функцију. То омогућава swizzling и forward invocation.

По чему се категорије (Categories) разликују од проширења (Extensions)?

Category (@interface ClassName (Name)) додаје метода било којој класи (укључујући системске) без наслеђивања. Extension (@interface ClassName ()) се декларише у .m датотеци и може додавати property и ivar. Category не може додавати ivar, extension — може.

Шта су блокови (Blocks) у Objective-C-у?

Blocks — анонимне функције са синтаксом ^(параметри) { тело }, које хватају променљиве из контекста. Аналогно ламбдама у C++ и closures-има у Swift-у. Захтевају __weak за спречавање retain cycles-а при хватању self-а. Користе се у UIKit-у, GCD-у и Foundation-у.

Која је разлика између ARC-а и MRC-а?

MRC — ручно бројање референци: програмер позива retain, release, autorelease. ARC — аутоматско: компилатор убацује retain/release на основу статичке анализе. ARC није GC — објекти се ослобађају одмах при нулирању бројача. ARC подржава __weak и __strong модификаторе.

Могу ли се Objective-C и Swift користити у истом пројекту?

Да, кроз Bridging Header. Swift види Objective-C кроз ово заглавље, Objective-C види Swift кроз -Swift.h. Swift класе морају бити наслеђене од NSObject-а и означене са @objc. Struct и enum из Swift-а нису видљиви Objective-C-у директно.

Закључци

  • Objective-C — строги надскуп C-а са динамичким runtime-ом и синтаксом порука за Cocoa/Cocoa Touch
  • Message passing — позиви кроз [object method] са динамичком диспечеризацијом кроз objc_msgSend и могућношћу swizzling-а
  • Categories — додавање метода постојећим класама без наслеђивања, укључујући системске Apple класе
  • Blocks — анонимне функције са затварањем, које захтевају __weak за спречавање retain cycles-а
  • ARC vs MRC — еволуција од ручног retain/release до аутоматског бројања референци кроз компилатор
  • Bridging Header — механизам заједничког рада Swift-а и Objective-C-а у једном пројекту за фазну миграцију
  • Легаси значај — око 35% апликација App Store-а садржи Objective-C код који захтева подршку

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође