YDC — Pizza Powered iOS
248 subscribers
67 photos
99 links
Young Da Code 👨‍💻
Первый командный дайджест о мобильной разработке 🍕
Download Telegram
😏 🔍 Наблюдаемость на мобилке — больше, чем логи.
Kodeco
выпустили свежий туториал по observability в iOS.

Ребята показали, как использовать OpenTelemetry на мобильных устройствах:
🏆собирать performance-транзакции,
🏆писать логи и события,
🏆анализировать краши и аномалии через MetricKit.

Инструмент мощный — в умелых руках можно построить полную картину поведения приложения, почти как на сервере.

⚙️ При этом схожий результат можно получить и проще — например, настроив Sentry: там тоже есть трассировки, логи, краши и удобная интеграция с приложением и CI/CD.
DX, конечно, в Senty гораздо выше, и продукт мощнее, но за это надо платить.


У инструментов разные акценты:
👉 OpenTelemetry — открытый стандарт, гибкость, но больше ручной настройки.
👉 Sentry — готовая экосистема, но с ограничениями по лицензии и стоимости.

И в итоге вопрос не в “что выбрать”, а зачем вообще наблюдаемость нужна.


Даже базовый уровень метрик и логов, как в туториале, даёт огромный потенциал для роста — понимания производительности, стабильности и пользовательского опыта.



📈 Наблюдаемость — ключ к зрелой мобильной разработке.
Это то, что помогает не просто чинить баги, а понимать продукт изнутри.

#L #iOS #observability #OpenTelemetry #Sentry #MetricKit #performance #mobileengineering

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4💋2
😄ARC, что внутри?

Казалось бы, тема пройдена вдоль и поперек, однако на технических интервью я периодически встречаю недопонимание принципов работы ARC даже у опытных разработчиков

⚡️Самый важный момент:

ARC "живет" только при компиляции


Он не отслеживает объекты в рантайме, не решает, когда освобождать память. Его задача - вставить в скомпилированный код вызовы функций, которые при MRC в Objective-C разработчик расставляет самостоятельно:

👉 objc_retain(ptr) - увеличивает счетчик ссылок объекта
👉 objc_release(ptr) - уменьшает счетчик
👉 objc_autorelease(ptr) - отложенное уменьшение счетчика, сегодня редкий кейс, об этом чуть ниже

Роль рантайма же - слепое исполнение инструкций. Если счётчик достигает нуля, объект немедленно деаллоцируется: вызывается deinit, освобождаются stored-свойства, память возвращается в кучу.

Что до счётчика ссылок - он хранится в заголовке объекта в куче и создаётся при аллокации объекта. Из Swift-кода доступа туда не получить

🤔 Что по autorelease?

Используется редко, но стоит упомянуть в контексте autoreleasepool. ARC вставляет autorelease только тогда, когда на этапе компиляции не может точно определить момент окончания владения объектом:

👉 Границы Swift Objective-C
👉 Объекты с атрибутом
@autorelease


Важный момент: autorelease не откладывает деаллокацию. Он откладывает выполнение release в конце блока autoreleasepool, итерации runloop'а или при завершении потока

Именно поэтому autoreleasepool внутри циклов так важен для управления памятью. Без него множество больших объектов будут накапливаться в пуле до конца итерации runloop'а, вызывая скачок потребления памяти

Итоговая модель выглядит так:

1️⃣ Swift-код
2️⃣ ARC на этапе компиляции вставляет вызовы retain/release/autorelease
3️⃣ Рантайм аллоцирует объект с заголовком
4️⃣ Retain → увеличивает счётчик. Autorelease → добавляет объект в пул (счётчик не меняется)
5️⃣ Пул завешается → выполняются release для всех объектов в пуле
6️⃣ Если счётчик == 0 → немедленная деаллокация.

💫 Надеюсь, сегодня мне удалось повысить понимание этого процесса: что решает компилятор, что слепо исполняет рантайм и где ответственность переходит к разработчику

📎 Что почитать?

Постарше
Посвежее
Очень старая дока по ObjC, но многое актуально и для Swift

#iOS #Swift #ARC #MemoryManagement #Performance

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥321
😏 Разберём разницу между some View и AnyView в SwiftUI. Тема не новая, но споры о правильном использовании периодически возвращаются.

Коротко:
some View сохраняет конкретный тип View на этапе компиляции.
AnyView стирает тип и оставляет только «какой-то View» на этапе выполнения.

Когда мы пишем:
var body: some View {
Text("Cowabunga")
}


Мы говорим компилятору:
тип конкретный и известен, но имя типа скрыто.

SwiftUI при этом:
- строит статическое дерево типов
- может оптимизировать diff
- лучше отслеживает identity View
- эффективнее обновляет UI

А с AnyView:
AnyView(Text("Cowabunga"))


Мы теряем информацию о реальном типе и часть работы переносится в runtime.

SwiftUI больше не знает:
- какая структура View внутри
- как оптимизировать обновления

🍕 Классический пример
func content(isLoggedIn: Bool) -> some View {
if isLoggedIn {
return HomeView()
} else {
return LoginView()
}
}


Компилятор ругается, потому что возвращаются разные типы.

Можно быстро пофиксить так:
func content(isLoggedIn: Bool) -> AnyView {
if isLoggedIn {
return AnyView(HomeView())
} else {
return AnyView(LoginView())
}
}


Работает, но ухудшает оптимизации SwiftUI, да и ревью вряд ли пройдет.

😅 Нормальный SwiftUI-подход - использовать ViewBuilder.
@ViewBuilder
func content(isLoggedIn: Bool) -> some View {
if isLoggedIn {
HomeView()
} else {
LoginView()
}
}


SwiftUI создаёт:
ConditionalContent<HomeView, LoginView>


И сохраняет типовую информацию для оптимизаций.

Когда AnyView действительно нужен:
- массив разных View
- runtime injection View
- API, где нельзя использовать generics

Например:
let cells: [AnyView] = [
AnyView(ProfileHeaderView()),
AnyView(SettingsRow(...))
]


🍕 Можно сформулировать простое правило:
Если SwiftUI может знать тип на этапе компиляции → используем some View.
Если тип появляется только во время выполнения → используем AnyView.

AnyView не зло, но его легко начать использовать как костыль. Поэтому имеет смысл ограничивать использование или подсвечивать его линтером.

#R #SwiftUI #Performance #Architecture

👏
Please open Telegram to view this post
VIEW IN TELEGRAM
71