Objective-C — 1980-ci illərdə Bred Koks tərəfindən yaradılmış dinamik mesaj göndərmə ilə proqramlaşdırma dili. Apple NeXTSTEP, sonra isə iOS SDK üçün əsas dil kimi Objective-C-ni seçdi. Programming With Objective-C — mesaj sintaksisi və yaddaş idarəçiliyinə giriş.
Əsas məqamlar
Objective-C — C-ni Smalltalk üslubunda obyekt-yönümlü proqramlaşdırma imkanları ilə genişləndirən proqramlaşdırma dili. Objective-C kodu LLVM və ya GCC vasitəsilə nativ maşın koduna kompilyasiya olunur, C ilə tam geriyə uyğunluğu qoruyur — istənilən C kodu Objective-C-də düzgündür.
Apple 1997-ci ildə NeXT-i (Objective-C ilə birlikdə) satın aldı. Dil macOS üçün Cocoa və Cocoa Touch — iOS üçün framework-lərin əsasına çevrildi. 2014-cü ildən Apple Swift-i əvəz kimi təqdim edir, lakin Objective-C legacy layihələri və bəzi sistem framework-ləri üçün kritik əhəmiyyətini qoruyur. Apple-ın məlumatına görə (WWDC 2024), App Store-dakı tətbiqlərin təxminən 35%-i hələ də Objective-C kodu ehtiva edir.
Əsas xüsusiyyət — dinamik runtime. Swift-dən fərqli olaraq, burada metod çağırışları kompilyasiya mərhələsində həll olunur, Objective-C isə objc_msgSend funksiyası vasitəsilə icra zamanı mesaj göndərir. Bu, metodları uçuş zamanı yenidən təyin etməyə (method swizzling), sinifləri dinamik əlavə etməyə və mövcud olmayan sektorlar üçün forward invocation istifadə etməyə imkan verir.
İstənilən C kodu Objective-C-də düzgündür. Obyekt üstqurumu siniflər (@interface/@implementation), kateqoriyalar, protokollar (@protocol) və dinamik tipləşdirmə (id) əlavə edir. Fayllar .m (icra) və .h (başlıqlar) genişlənmələrinə malikdir.
Mesaj sintaksisi — Objective-C-nin C-bənzər dillərdən əsas fərqi. object.method(argument) əvəzinə [object method:argument] istifadə olunur. Hər mesaj runtime-da metodun icrasını dinamik axtaran objc_msgSend-dən keçir.
// Adlandırılmış parametrlərlə mesaj sintaksisi
NSString *greeting = [NSString stringWithFormat:@"Hello, %@", name];
// İç-içə mesajlar
NSArray *sortedArray = [[array sortedArrayUsingSelector:@selector(compare:)] copy];
// Instrospeksiya vasitəsilə tip yoxlanışı
if ([object isKindOfClass:[UIView class]]) {
UIView *view = (UIView *)object;
view.backgroundColor = [UIColor redColor];
}Dynamic dispatch metodları runtime-da yenidən təyin etməyə (method swizzling) imkan verir — güclü, lakin təhlükəli texnika. Məsələn, AFNetworking və Aspects kimi framework-lər URLSession çağırışlarını ələ keçirmək üçün swizzling istifadə edir. Apple xəbərdarlıq edir: swizzling səhv istifadə edildikdə sistem framework-lərinin işini poza bilər.
Categories — Objective-C-nin mövcud siniflərə (NSString və UIView daxil olmaqla sistem sinifləri də daxil) miras olmadan və mənbə koduna giriş olmadan metod əlavə etmək üçün unikal imkanı. Kateqoriyalar @interface ClassName (CategoryName) vasitəsilə elan edilir.
// UIColor+Hex.h faylı — UIColor üçün kateqoriya
@interface UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex;
@end
// UIColor+Hex.m faylı — icra
@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];
}
@endExtensions (Class Extension) — .m faylında adsız elan edilmiş xüsusi kateqoriya növü: @interface ClassName (). Kateqoriyalardan fərqli olaraq, extensions təkcə metodları deyil, həm də ivar (instance variables) və property əlavə edə bilər. Extensions daxili API-ni xarici modullardan gizlətmək üçün istifadə olunur.
Blocks — Objective-C-də xarici görünmə sahəsindən dəyişənləri ələ keçirən anonim funksiyalar. Blok sintaksisi: ^(int x) { return x * 2; }. Blocks UIKit-də callback handler-lər, Grand Central Dispatch-də asinxron tapşırıqlar və NSArray/NSDictionary kolleksiyalarında funksional əməliyyatlar üçün istifadə olunur.
// Blok tipinin elanı
typedef void (^CompletionBlock)(BOOL success, NSError *error);
// Parametr kimi blok
- (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);
}
});
}Yaddaş idarəçiliyi bloklarda kritik əhəmiyyətlidir. Bloklar self-i güclü istinadla ələ keçirir, bu da birbaşa istifadədə retain cycle yaradır. Həlli — __weak typeof(self) weakSelf = self, blok daxilində sonrakı yoxlama ilə. Bu problem Swift-də [weak self] capture lists vasitəsilə tam həll edilmişdir.
Objective-C MRC (Manual Reference Counting)-dən ARC (Automatic Reference Counting)-ə qədər yol keçmişdir. MRC-də proqramçı əl ilə retain (sayğacı artırma), release (azaltma) və autorelease (təxirə salınmış release) çağırırdı. Bu çağırışlardakı səhvlər yaddaş sızmalarına və ya dangling pointers səbəbindən crash-lərə gətirib çıxarırdı.
| Əməliyyat | MRC | ARC |
|---|---|---|
| Obyektin yaradılması | [[Object alloc] init] | [[Object alloc] init] |
| İstinadın saxlanması | [object retain] | Avtomatik |
| Azad edilmə | [object release] | Avtomatik |
| Avtoazadetmə | [object autorelease] | Avtomatik (tələb olunmur) |
| Weak istinad | __weak mövcud deyildi | __weak (avtomatik nil) |
ARC Xcode 4.2 və LLVM 3.0 (2011)-da təqdim edildi. Kompilyator obyektlərin lifetime-nı təhlil edərək kompilyasiya mərhələsində avtomatik retain/release əlavə edir. ARC zibil yığımı (garbage collection) deyil — bu, avtomatik əlavələrlə statik analizdir. Objective-C ARC Swift ARC ilə uyğundur: hər ikisi runtime səviyyəsində eyni istinad sayma sistemindən istifadə edir.
Objective-C və Swift-in bir layihədə birgə istifadəsi legacy layihələr üçün adi təcrübədir. Apple Bridging Header — Swift-in Objective-C siniflərini, Objective-C-nin isə NSObject-dən miras alan Swift siniflərini görməsi üçün avtomatik yaradılan faylı təqdim edir.
// ProjectName-Bridging-Header.h
// Swift bu başlıqları avtomatik görür
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"Objective-C-dən Swift-ə miqrasiya — mərhələli proses. Yeni fayllar Swift-də yazılır, köhnələr tədricən refaktor edilir. Bridging Header Objective-C layihəsinə ilk Swift faylı əlavə edildikdə avtomatik yaradılır. Əks görünmə üçün (ObjC → Swift) Xcode @objc ilə işarələnmiş Swift sinifləri üçün @interface ehtiva edən
// Objective-C-dən görünən Swift sinfi
@objc class SwiftRouter: NSObject {
@objc func navigateToProfile(userId: Int) {
// icra
}
}Məhdudiyyətlər: Swift value-tiplər (struct, enum) Objective-C-dən birbaşa görünmür — onları @objc ilə class-a bükmək lazımdır. Swift-də Generics Objective-C-dən məhdud şəkildə əlçatandır. Tövsiyə olunan yanaşma — yeni kodu Swift-də yazmaq, mövcud Objective-C kodunu isə yalnız müvafiq funksionallıq dəyişdikdə refaktor etmək.
Objective-C-nin Swift-dən üstünlüyü — runtime-a tam giriş. Method swizzling, icra zamanı metodların icrasını dəyişdirmə, miras olmadan sistem metodlarını yenidən təyin etməyə imkan verir. Aspects və JRSwizzle kimi kitabxanalar bu imkanı AOP (aspekt-yönümlü proqramlaşdırma) — monitorinq, analitika və loglama üçün istifadə edir.
Forward invocation — daha bir runtime imkanı: əgər obyekt sektora cavab vermirsə, sistem forwardInvocation: çağırır, mesajı başqa obyektə yönləndirməyə imkan verir. Bu, Objective-C-də (NSProxy) Proxy nümunəsinin əsasıdır, gecikmiş inisializasiya və paylanmış obyektlər üçün istifadə olunur.
Apple yeni kodda runtime hiylələrinin istifadəsini minimuma endirməyi, Swift-in statik tipləşdirməsinə üstünlük verməyi tövsiyə edir. Lakin legacy layihələrdə objc_msgSend, method_exchangeImplementations və objc_getAssociatedObject bilikləri mövcud kod bazasını dəstəkləmək üçün zəruridir.
Objective-C property-ni getter/setter ilə ivar üzərində sintaktik şəkər kimi dəstəkləyir. atomic/nonatomic, strong/weak/copy, readonly/readwrite və assign/retain modifikatorları yaddaş davranışını və thread təhlükəsizliyini müəyyən edir. Key-Value Observing (KVO) — runtime-a daxil edilmiş xassə dəyişikliklərini müşahidə mexanizmi: istənilən obyekt addObserver vasitəsilə başqa obyektin xassə dəyişikliklərinə abunə ola bilər.
Tez-tez verilən suallar
Metod çağırışı [object selector:argument] kimi görünür. Mesaj runtime-da icranı dinamik tapan objc_msgSend-dən keçir. Selektör metod adıdır (@selector(methodName)), funksiya göstəricisi deyil. Bu, swizzling və forward invocation-a imkan verir.
Category (@interface ClassName (Name)) hər hansı sinifə (sistem sinifləri də daxil) miras olmadan metod əlavə edir. Extension (@interface ClassName ()) .m faylında elan edilir və property və ivar əlavə edə bilər. Category ivar əlavə edə bilməz, extension — edə bilər.
Blocks — ^(parametrlər) { bədən } sintaksisi ilə anonim funksiyalar, kontekstdən dəyişənləri ələ keçirir. C++-da lambdaların və Swift-də closures-un analoqu. Self ələ keçirərkən retain cycles qarşısını almaq üçün __weak tələb edir. UIKit, GCD və Foundation-da istifadə olunur.
MRC — əl ilə istinad sayı: proqramçı retain, release, autorelease çağırır. ARC — avtomatik: kompilyator statik analiz əsasında retain/release əlavə edir. ARC GC deyil — obyektlər sayğac sıfırlandıqda dərhal azad edilir. ARC __weak və __strong modifikatorlarını dəstəkləyir.
Bəli, Bridging Header vasitəsilə. Swift Objective-C-ni bu başlıq vasitəsilə görür, Objective-C Swift-i
Nəticələr
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun