Watchpoint — шта је то, врсте и подешавање тачака посматрања у Xcode

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

Watchpoint (тачка посматрања) — механизам отклањања грешака који зауставља извршење програма при промени вредности наведене променљиве или меморијске области. За разлику од breakpoint-а, који је везан за линију кода, watchpoint прати промену података без обзира на то у ком делу програма је дошло до измене. Према Apple Developer Documentation, watchpoint-ови су незаменљиви при отклањању грешака у тркама података, неочекиваним променама својстава и праћењу животног циклуса објеката.

Главно

  • Watchpoint — тачка посматрања промене променљиве, која се активира при сваком упису у наведену меморијску област.
  • Xcode подржава watchpoint-ове преко GUI и конзоле LLDB, укључујући условне тачке посматрања.
  • Променљиве-својства објеката захтевају watchpoint са навођењем меморијске адресе, а не имена променљиве.
  • Перформансе са watchpoint-овима значајно опадају због хардверског надгледања сваке операције уписа.
  • Watchpoint-ови се не чувају између сесија отклањања грешака — морају се поново поставити након сваког покретања.

Шта је watchpoint и принцип рада

Watchpoint — механизам дебагера који зауставља извршење програма када се промени вредност на наведеној меморијској адреси. Ако breakpoint реагује на достизање одређене линије кода, watchpoint реагује на упис у одређену меморијску ћелију — без обзира на то који део кода је извршио тај упис. То га чини незаменљивим при тражењу неочекиваних модификација променљивих, посебно у вишенитним апликацијама.

Принцип рада заснива се на хардверској подршци процесора. Савремени ARM чипови (Apple Silicon, Qualcomm Snapdragon) пружају од 4 до 8 хардверских watchpoint регистара. Када процесор изврши инструкцију уписа на адресу која се поклапа са watchpoint-ом, настаје хардверски прекид који дебагер пресреће. Ако хардверски регистри понестану, LLDB прелази у софтверски режим — проверава сваку инструкцију уписа корак по корак, што успорава извршење десетинама пута.

Према ARM Architecture Reference Manual, хардверски watchpoint-ови раде на нивоу модула Data Watchpoint and Trace (DWT) и не захтевају измену извршног кода. Време реакције на активирање износи јединице наносекунди, што омогућава праћење чак и високофреквентних промена променљивих у петљама обраде података, попут аудио бафера или видео оквира.

Када је watchpoint ефикаснији од breakpoint-а

Watchpoint је незаменљив када знате која се променљива мења, али не знате одакле. Типични сценарији: вредност својства frame у UIView мења се без видљивог разлога; бројач у позадинској нити ресетује се непредвидиво; заставица isLoading пребацује се раније него што се завршио мрежни захтев. У сваком од ових случајева, постављање breakpoint-а на сва места где може доћи до уписа је непрактично. Watchpoint решава проблем једном командом.

Врсте watchpoint-ова и начини постављања

Xcode и LLDB подржавају три врсте watchpoint-ова: watchpoint set variable — за посматрање локалне променљиве; watchpoint set expression — за посматрање израза који враћа адресу; watchpoint set — за посматрање сирове меморијске адресе. Свака врста има своју област примене.

Врста watchpoint-аLLDB командаПримена
Променљиваwatchpoint set variable -w write self.countЛокалне и глобалне променљиве, својства структура
Изразwatchpoint set expression -w write -- &self->mutex.lockПоља структура преко показивача, елементи низова по индексу
Адресаwatchpoint set -w write 0x600000c4b80Конкретна меморијска адреса из претходног излаза LLDB

Постављање преко GUI Xcode

У Xcode-у watchpoint се може поставити преко Debug Area: зауставите се на breakpoint-у, пронађите потребну променљиву у панелу Variables View, кликните десним тастером и изаберите Watch Variable. Xcode аутоматски извршава команду watchpoint set variable са исправним именом променљиве и контекстом. Након тога дебагер ће се заустављати при свакој промени вредности — погодно за брзо отклањање грешака без преласка на конзолу. Међутим, овај метод ради само док је променљива у домену видљивости тренутног оквира.

swift
func processItems(_ items: [String]) {
    var index = 0
    // Поставите watchpoint на index преко GUI-ја:
    // зауставите се овде, десни клик → Watch Variable
    for item in items {
        index += 1
        print("Item \(index): \(item)")
    }
}

Управљање watchpoint-овима преко LLDB

LLDB пружа комплетан скуп команди за управљање watchpoint-овима из конзоле. Ово даје већу контролу од GUI-ја: можете одредити величину области посматрања, поставити услов активирања, креирати watchpoint-ове на адресама добијеним из израчунатих израза и аутоматски извршавати радње при активирању. Интерфејс командне линије је посебно користан при отклањању грешака у сложеним сценаријима где је потребно брзо мењати параметре посматрања.

Основне watchpoint команде

Команда watchpoint set variable прихвата име променљиве узимајући у обзир домен видљивости: за self својства у Objective-C користите self->_property, за Swift — self.property. Параметар -w write поставља праћење уписа, -w read — читања (режим доступан само на неким архитектурама), -s size — величину области у бајтовима. Након постављања watchpoint-а, листа се може видети командом watchpoint list.

lldb
(lldb) watchpoint set variable -w write -s 8 self.balance
Watchpoint 1: addr = 0x600000c4b80 size = 8 state = enabled  type = w
    watchpoint spec: 'self.balance'
(lldb) watchpoint set expression -w write -- self->items._storage
Watchpoint 2: addr = 0x600003a4c00 size = 8
(lldb) watchpoint list
1: location = 0x600000c4b80, type = write, variable = '_balance'
2: location = 0x600003a4c00, type = write, expression = 'self->items._storage'

Условни watchpoint-ови

Као и breakpoint-ови, watchpoint-ови подржавају условно активирање. Параметар -c поставља услов у Swift или Objective-C. На пример, watchpoint са условом newValue > 1000 зауставиће се само када уписана вредност пређе хиљаду. Ово је критично при отклањању грешака у петљама или сензорима који генеришу хиљаде промена у секунди — иначе би се дебагер заустављао при свакој промени, чинећи рад немогућим.

lldb
(lldb) watchpoint set variable -w write self.temperature -c "(int)$newValue > 100"
Watchpoint 3: addr = 0x600000e4a20, condition = '(int)$newValue > 100'
(lldb) watchpoint modify 3 -C "po self.temperature" -G true
// Аутоматски забележи вредност и настави извршење

Watchpoint-ови за својства објеката и колекција

Посебност watchpoint-ова за својства објеката Objective-C и Swift — watchpoint се поставља не на име својства, већ на адресу поља ivar (променљиве инстанце) у меморији објекта. То значи да при сваком новом алодирању објекта (на пример, при поновном креирању ViewController-а), watchpoint постаје неважећи јер се меморијска адреса променила. За стално посматрање својства кроз рестартове потребно је поново поставити watchpoint у тренутку иницијализације објекта.

Watchpoint на елементе колекција

Посматрање елемената низова и речника захтева израчунавање адресе конкретног елемента. На пример, за посматрање трећег елемента низа користите watchpoint set expression -- &array[2]. Ако низ поново алодира интерни бафер (при додавању елемената преко капацитета), watchpoint постаје неважећи — LLDB пријављује грешку Watchpoint 1 has an invalid address. У таквим случајевима потребно је поново поставити watchpoint након промене величине колекције.

lldb
(lldb) expr var $arr = [10, 20, 30, 40, 50]
(lldb) watchpoint set expression -w write -- &$arr[2]
Watchpoint 4: addr = 0x1000a4b20, size = 8
(lldb) expr $arr[2] = 99
Watchpoint 4 hit: old value: 30, new value: 99

Праћење retain count-а преко watchpoint-а

У Objective-C-у можете пратити retain count објекта постављањем watchpoint-а на поље retainCount у структури objc_object. LLDB то извршава преко watchpoint set expression -w write -- (int*)[object retainCount]. Међутим, за Swift објекте са ARC-ом (Automatic Reference Counting) retain count није директно доступан — уместо тога користите Instruments или Memory Graph Debugger за анализу цурења меморије. Према Apple-у, watchpoint-ови на retain count раде само у Debug верзијама са искљученом ARC оптимизацијом.

Ограничења и перформансе watchpoint-ова

Watchpoint-ови имају низ ограничења која треба узети у обзир. Главно — број хардверских watchpoint-ова је ограничен на 4–8 регистара на ARM архитектури и до 4 на x86. Када су сви хардверски регистри заузети, LLDB прелази у режим софтверског watchpoint-а: мења сваку инструкцију уписа у праћеном опсегу да би генерисао изузетак. То успорава извршење 10–50 пута, због чега се у пракси препоручује коришћење не више од 2–3 активна watchpoint-а истовремено.

Друго ограничење — неважење watchpoint-ова при преалокацији меморије. Приликом рада сакупљача отпада или ARC-а, када се објекат премешта у меморији (у језицима са компактизацијом хипа), адреса watchpoint-а постаје неисправна. У Swift-у и Objective-C-у ARC не премешта објекте, али реалокација низова и стрингова доводи до истог ефекта. LLDB упозорава на ово поруком Watchpoint N address (0x...) doesn't contain a valid allocation.

Треће ограничење — видљивост променљивих. Watchpoint на локалну променљиву ради само док се та променљива налази у домену видљивости тренутног стек оквира. Чим се функција заврши, watchpoint се аутоматски брише. За посматрање глобалних променљивих или поља дуготрајних објеката, watchpoint се чува до експлицитног брисања преко watchpoint delete или до завршетка процеса.

lldb
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete               # Удалить все watchpoints
2 watchpoints deleted.
(lldb) watchpoint disable 1             # Временно отключить
(lldb) watchpoint enable 1              # Включить снова

Према ARM-у, watchpoint-ови на Apple Silicon (M1–M4) подржавају величину праћене области од 1 до 8 бајтова. За посматрање структура већих од 8 бајтова потребно је поставити више watchpoint-ова на свако поље. Ово је важно при отклањању грешака у сложеним структурама података, попут CGRect (16 бајтова) или UIEdgeInsets (16 бајтова).

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

Која је разлика између watchpoint-а и breakpoint-а?

Breakpoint је везан за линију кода — зауставља се по њеном достизању. Watchpoint је везан за меморијску адресу — зауставља се при упису на ту адресу из било ког дела програма. Watchpoint тражи „ко мења вредност“, breakpoint — „шта се дешава на овој линији“.

Колико watchpoint-ова се може поставити истовремено?

4–8 хардверских на ARM-у (укључујући Apple Silicon). Прекорачење пребацује watchpoint у софтверски режим, што успорава извршење 10–50 пута. Препоручује се не више од 2–3 активна watchpoint-а истовремено.

Зашто watchpoint престаје да ради након поновног покретања апликације?

Watchpoint-ови се не чувају између сесија отклањања грешака. При сваком новом покретању меморијске адресе се мењају и watchpoint се мора поново поставити. Изузетак су watchpoint-ови на глобалне променљиве са фиксном адресом.

Може ли се поставити watchpoint на Swift својство?

Да, али watchpoint се поставља на ivar (подржавајуће складиште) својства, а не на само својство. У Swift-у користите watchpoint set variable self.property — LLDB ће аутоматски пронаћи одговарајући ivar по имену својства.

Како watchpoint утиче на перформансе апликације?

Хардверски watchpoint не утиче на перформансе — прекид се дешава на нивоу процесора. Софтверски (при истрошењу хардверских регистара) успорава извршење 10–50 пута, јер LLDB проверава сваку инструкцију уписа.

Резиме

  • Watchpoint — тачка посматрања промене меморије, која се активира при сваком упису на наведену адресу из било које нити.
  • Хардверски watchpoint-ови користе DWT регистре процесора и не успоравају извршење, али су ограничени на 4–8 регистара.
  • LLDB подржава три врсте watchpoint-ова: на променљиву, на израз и на сирову меморијску адресу.
  • Условни watchpoint-ови се активирају само при испуњењу одређеног израза — неопходно за отклањање грешака високофреквентних промена.
  • Watchpoint-ови на својства објеката и елементе колекција постају неважећи при преалокацији меморије.
  • Watchpoint-ови се не чувају између сесија и бришу се при изласку променљиве из домена видљивости.
  • Watchpoint — најбољи избор када је променљива позната, али место њене измене није, посебно у вишенитном коду.

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

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

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

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