Objective-C — о разделе
Черновик раздела. Материалы будут дополняться; ниже — структура, ключевые идеи messaging/runtime и черновые статьи для чтения legacy-кода Apple.
Objective-C — язык Apple до доминирования Swift:
- сообщения в стиле Smalltalk поверх синтаксиса C;
- фреймворки Foundation, UIKit, AppKit;
- ARC (Automatic Reference Counting) для управления памятью объектов.
Раздел нужен для чтения legacy-кода iOS/macOS, поддержки старых модулей и понимания bridge в Swift.
| Материал | Зачем |
|---|---|
| История языка | NeXT, Apple, переход к Swift |
| Первая программа | Xcode, clang, Foundation |
| Swift intro | Современный стек Apple |
| Smalltalk intro | Модель сообщений |
Что такое Objective-C простыми словами
Objective-C = C + объектная модель с сообщениями. Вместо obj.method(arg) пишут [obj method:arg]. Runtime динамический: можно отправить сообщение объекту, даже если метод объявлен в category позже.
| Аспект | Objective-C | Swift |
|---|---|---|
| Синтаксис | [ ], @ directives | Современный, типобезопасный |
| Null для объектов | nil | Optionals |
| Память | ARC (раньше MRC вручную) | ARC + value types |
| Новые API Apple | Legacy headers, @objc | Swift-first |
Новые приложения пишут на Swift; Objective-C остаётся в системных фреймворках, open source (AFNetworking era, FFmpeg bindings) и миллионах строк legacy в App Store.
Планируемое содержание
| № | Тема | Статус |
|---|---|---|
| 1 | История языка | черновик |
| 2 | Синтаксис, @interface, @implementation | планируется |
| 3 | Messaging, nil, протоколы | планируется |
| 4 | Memory management — MRC и ARC | планируется |
| 5 | Foundation — NSString, NSArray, NSDictionary | планируется |
| 6 | Interop Swift ↔ Objective-C | планируется |
| 7 | Первая программа | черновик |
| 8+ | UIKit lifecycle, миграция на Swift | планируется |
Ключевые идеи раздела
Messaging, не вызов метода
NSString *s = @"Hello";
NSString *upper = [s uppercaseString];
Компилятор превращает в objc_msgSend. Динамическая диспетчеризация — основа swizzling и KVO (Key-Value Observing) в legacy-коде.
Directives @
| Директива | Назначение |
|---|---|
@interface / @implementation | Объявление и реализация класса |
@property | Геттер/сеттер + backing ivar |
@protocol | Аналог interface в Java |
@selector | Указатель на метод для runtime |
Literals @"...", @[], @{} | NSString, NSArray, NSDictionary |
ARC
Компилятор вставляет retain/release/autorelease автоматически. В @autoreleasepool объекты освобождаются в конце scope. До 2011 года MRC (Manual Reference Counting) требовал ручного release — читать старый код без паники.
Categories и protocols
Category добавляет методы существующему классу без подкласса. Protocol — контракт методов (<UITableViewDelegate>). Swift унаследовал идеи через extensions и protocols.
Инструменты
| Инструмент | Назначение |
|---|---|
| Xcode | IDE, симулятор, Interface Builder |
| clang | Компилятор Obj-C и Swift |
| Instruments | Профилирование памяти и CPU |
| lldb | Отладчик в терминале и Xcode |
Разработка Objective-C для Apple-платформ — на macOS. Linux GNUstep — нишевый путь вне основного раздела.
Порядок чтения
- История языка — NeXT → Apple → Swift.
- Первая программа — CLI Hello World,
@interface. - Messaging и Foundation (статьи 2–5).
- Bridging header и mixed Swift/Obj-C (статья 6).
Параллельно полезны C++ (синтаксис C) и Smalltalk (философия сообщений).
Кому подойдёт раздел
| Сценарий | Зачем Objective-C |
|---|---|
| Поддержка legacy iOS-модуля | Читать без полного rewrite |
| Mixed Swift/Obj-C проект | Bridging, @objc |
| Понимание Apple SDK | Многие headers Obj-C |
| Open source на GitHub | Старые библиотеки |
Новый UI-код — Swift; Objective-C — страховка для maintenance и собеседований в компаниях с длинной историей iOS.
Связанные разделы
| Раздел | Связь |
|---|---|
| Swift | Преемник, interop |
| Smalltalk | Messaging model |
| C++ | Синтаксическая база C |
| Мобильные приложения | Контекст платформы |
Статьи 2–6 в плане. Черновики истории и первой программы содержат рабочие команды clang и фрагменты @interface.
Пошаговый маршрут на две недели
| День | Задача | Результат |
|---|---|---|
| 1–2 | 7.md CLI Hello World | clang -fobjc-arc работает |
| 3 | Literals @"", @[], @{} | Foundation collections |
| 4 | 1.md история + messaging | Понимание NeXT lineage |
| 5 | @property strong/weak/copy | ARC qualifiers |
| 6 | Protocol + delegate (read-only) | UIKit header pattern |
| 7 | Bridging header в mixed project | Swift вызывает Obj-C |
| 8–10 | Legacy file на GitHub | Аннотации в .m |
Не начинайте с storyboard. Сначала CLI + Foundation, затем один legacy ViewController только для чтения. Так быстрее связывается messaging с реальным кодом.
Учебный разбор retain cycle
@interface Worker : NSObject
@property (nonatomic, copy) void (^onDone)(void);
@end
@implementation Worker
- (void)start {
self.onDone = ^{
[self cleanup]; // cycle: block → self → block
};
}
- (void)cleanup {}
@end
Исправление — __weak typeof(self) weakSelf = self; в block. Отладка — Instruments Leaks и отладка.
Foundation literals — шпаргалка
NSString *s = @"text";
NSNumber *n = @42;
NSArray *a = @[s, n];
NSDictionary *d = @{@"key": s};
for (NSString *item in a) { NSLog(@"%@", item); }
| Literal | Класс |
|---|---|
@"..." | NSString |
@[] | NSArray |
@{} | NSDictionary |
@42 | NSNumber |
Interop Swift (кратко)
- Bridging header:
#import "LegacyManager.h". - Swift class для Obj-C:
@objcMembers class Foo: NSObject. - Generated header
Target-Swift.hв.m.
Подробнее — Swift intro, Git workflow — Git.
Упражнения
- Соберите Hello World из 7.md без Xcode GUI.
- Class
Counterс-incrementи propertycount. NSArrayиз трёх имён — fast enumeration +NSLog.- Намеренный retain cycle → Instruments.
- Найдите
@protocolв UIKit header. - Swift
@objcclass, вызов из.m. - Stack trace с
objc_msgSend— найти selector. - Сравните
nilmessaging с Swift Optional. - Прочитайте open source
.mна GitHub. - Объясните
-vs+на примереNSString.
Troubleshooting
| Симптом | Причина | Решение |
|---|---|---|
| Foundation.h not found | Нет -framework Foundation | Флаг clang |
| Unrecognized selector | Typo или wrong class | po [obj class] в lldb |
| Bridging header missing | Build Settings | SWIFT_OBJC_BRIDGING_HEADER |
| Duplicate symbol | .m в двух targets | Target Membership |
| Leak | strong в block | weakSelf |
| Swift invisible in Obj-C | Нет @objc | NSObject + @objcMembers |
| Autorelease warning | Hot loop | @autoreleasepool |
| Code signing | Provisioning | Automatic signing |
FAQ
Нужен ли Objective-C новичку Apple-разработчику? Для новых app — Swift достаточно. Obj-C — legacy, headers, mixed targets.
Чем messaging отличается от вызова функции? Runtime ищет IMP по selector; позднее binding, categories.
Что такое selector?
Имя метода в runtime, тип SEL (stringWithFormat:).
Зачем @autoreleasepool?
Drain autorelease objects в scope CLI программ.
MRC ещё актуален? Только в очень старых кодовых базах.
Categories безопасны? Конфликт при одинаковых selectors — осторожно в categories на системных классах.
Blocks и GCD? Closures + Grand Central Dispatch — legacy concurrency до Swift async.
Obj-C без macOS? GNUstep — niche; iOS dev — macOS + Xcode.
Как читать .h?
@interface public; @implementation в .m.
Что такое instancetype?
Typed return для [[Class alloc] init].
IBOutlet / IBAction? Storyboard bindings; legacy UIKit.
Migration на Swift?
Module за module, bridging header, @objc exposure.
Где практиковать без устройства? Simulator; CLI Foundation на macOS.
Open source Obj-C? GitHub: старые iOS libs, FFmpeg bindings.
Связь со Smalltalk? Message passing без функционального Smalltalk runtime — Smalltalk intro.
Дополнительные упражнения раздела
- Xcode workspace: CLI tool + unit test target.
- Найдите
@protocolс@optionalв UIKit header. - Diagram retain graph: strong vs weak delegate.
- Crash log с
objc_msgSend— найти selector. - Mixed target: Swift вызывает Greeter.
iOS-сборка требует macOS. GNUstep на Linux не заменяет UIKit tutorial path.
Instruments и профилирование (обзор)
Instruments в Xcode профилирует Obj-C/Swift: Leaks, Time Profiler, Allocations. Legacy Obj-C часто показывает retain cycles в delegate chains — ищите strong delegate properties.
Ключевые префиксы Apple API
| Префикс | Происхождение |
|---|---|
| NS | NeXTstep / Foundation |
| UI | UIKit (iOS) |
| CG | Core Graphics (C) |
| CF | Core Foundation (C, toll-free bridge) |
Чтение headers проще, когда префикс указывает на слой стека.
Чек-лист раздела Objective-C
- Прочитана история
- Собран Hello World через clang или Xcode
- Объяснено отличие messaging от C function call
- Понятны ARC и
strong/weak - Открыт Swift intro для mixed targets
WWDC и migration resources
Apple публикует guides по постепенной миграции Obj-C → Swift: mixed targets, @objc exposure, nullability annotations в headers. Полезно при чтении legacy UIKit code.
Типичные символы в crash logs
| Symbol | Значение |
|---|---|
objc_msgSend | Dynamic dispatch |
-[Class method:] | Instance method |
+[Class method] | Class method |
Умение читать stack trace ускоряет отладку legacy apps.
FAQ (дополнение раздела)
Obj-C для App Store в 2026? Новые apps Swift; Obj-C для maintenance.
GNUstep карьера? Не для iOS jobs.
clang без Xcode? CLT enough for Foundation CLI.
Reading order summary? 1.md → 7.md → Swift interop.
Связанные материалы (итог)
| Статья | Тема |
|---|---|
| 1.md | История NeXT и Apple |
| 7.md | CLI Hello World |
| Swift | Современный стек |
| Git | Версионирование |
История Objective-C — черновик
Черновик — Brad Cox, Stepstone, NeXT, Apple и переход к Swift.
Первая программа на Objective-C — черновик
Черновик — Xcode, clang, Foundation и Hello World на macOS.
Objective-C — о разделе
Черновик раздела Objective-C — Cocoa, Apple legacy и связь со Swift.