Dayanma nöqtəsi (breakpoint) — kodda xüsusi bir işarədir, ona çatdıqda debuger proqramın icrasını vəziyyəti yoxlamaq üçün dayandırır. Apple Debugging Guide-a görə, breakpoint-lər proqramçıya dəyişənlərin qiymətlərini, çağırış yığınını görməyə və mənbə kodunu dəyişmədən addım-addım icra etməyə imkan verir. Bu, real vaxtda səhvlərin diaqnostikası və proqramın davranışının təhlili üçün əsas alətdir.
Əsas məqamlər
Breakpoint — mənbə kodunun müəyyən sətrində qoyulan aktiv işarədir, ona çatdıqda debuger icraçı axını məcburi dayandırır. Bu anda proqramçı proqramın vəziyyəti üzərində tam nəzarət əldə edir: cari görünmə sahəsindəki bütün dəyişənlərin qiymətlərinə baxa, çağırış yığınını təhlil edə, ixtiyari ifadələri yerinə yetirə və icranı addım-addım davam etdirə bilər. Breakpoint-lər olmasaydı, debug müvəqqəti print ifadələrinin sonsuz əlavə edilməsi və sonra silinməsinə çevrilərdi — bu yanaşma kodu çirkləndirir və interaktiv nəzarət təmin etmir.
Breakpoint-in əsas məqsədi səhvin mənbəyini lokallaşdırmaqdır. Proqram gözlənilənən şəkildə davrandıqda, proqramçı şübhəli hissədən əvvəl dayanma nöqtəsi qoyur və ardıcıl olaraq hansı məlumatların daxil olduğunu, dəyişənlərin necə dəyişdiyini və icranın hansı yolla getdiyini təhlil edir. Apple-a görə, mobil proqramlardakı səhvlərin 70%-dən çoxu məhz breakpoint-lər və addım-addım icra köməyilə aşkarlanır, statik kod təhlili ilə yox.
Breakpoint-lər release kompilyasiyasının performansına təsir etmir — onlar yalnız Debug konfiqurasiyasında kompilyasiya olunur. Xcode-da preprosessor direktivləri ilə debug kodunu əhatələyən xüsusi DEBUG bayrağı var. Bu, dayanma nöqtələrinin App Store-a düşməyəcəyini və son istifadəçilərin işini yavaşlatmayacağını təmin edir.
Prosessor breakpoint ilə qeyd olunmuş sətrə çatdıqda, aparat və ya proqram kəsilməsi baş verir. Xcode-da SIGTRAP mexanizmi istifadə olunur — debuger tərəfindən tutulan izləmə siqnalı. LLDB bütün axınları dayandırır, idarəni Xcode interfeysinə ötürür və proqramçının əmrini gözləyir: davam et (continue), keç (step over), daxil ol (step into) və ya çıx (step out).
func fetchUserData(userId: Int) {
// LLDB burada dayanacaq, əgər breakpoint qoyulubsa
let url = URL(string: "https://api.example.com/user/\(userId)")
var request = URLRequest(url: url)
request.httpMethod = "GET"
print("Fetching user \(userId)")
}
Yuxarıdakı nümunədə, let url = ... sətrində qoyulmuş breakpoint şəbəkə sorğusunun icrasından əvvəl hansı userId-nin funksiyaya ötürüldüyünü, URL-in düzgün qurulduğunu və sorğuda hansı başlıqların qoyulduğunu yoxlamağa imkan verir.
Xcode beş əsas breakpoint növü təqdim edir, hər biri xüsusi debug tapşırığını həll edir. Onların fərqlərini başa düşmək hər vəziyyət üçün optimal alət seçməyə və yalnız xətti dayanma nöqtələrindən istifadə ilə müqayisədə diaqnostika vaxtını 2-3 dəfə azaltmağa imkan verir.
| Breakpoint növü | Məqsəd | Aktivləşdirilmə |
|---|---|---|
| Line breakpoint | Kodun müəyyən sətrində dayanma | Redaktorda sətr nömrəsinə klik |
| Conditional breakpoint | Şərt yerinə yetirildikdə dayanma | Sağ klik → Edit Breakpoint → Condition |
| Symbolic breakpoint | Funksiya/metod çağırıldıqda dayanma | Breakpoint Navigator → + → Symbolic Breakpoint |
| Exception breakpoint | Istisna atıldıqda dayanma | Breakpoint Navigator → + → Exception Breakpoint |
| Error breakpoint | Səhv baş verdikdə dayanma (Swift) | Breakpoint Navigator → + → Swift Error Breakpoint |
Line breakpoint — ən geniş yayılmış növdür. Xcode redaktorunda sətr nömrəsinə bir kliklə qoyulur. Bu sətrə çatdıqda icra dayanır və proqramçı Debug Area paneli və ya LLDB konsolu vasitəsilə vəziyyəti təhlil edə bilər. Stack Overflow statistikasına görə, iOS proqramçılarının 85%-dən çoxu əsas debug aləti kimi məhz xətti breakpoint-lərdən istifadə edir, qalan növlər isə xüsusi ssenarilər üçün — məsələn, üçüncü tərəf kitabxanalarının debugu və ya istisnaların tutulması üçün istifadə olunur.
Symbolic breakpoint müəyyən metodun və ya funksiyanın çağırılması zamanı dayanmağa imkan verir, hətta həmin metodun mənbə koduna girişiniz olmasa belə. Sistem freymvorklarının debugu zamanı əvəzolunmazdır — məsələn, UIKit-in layoutSubviews-i çağırdığı anı tutmaq üçün. Konfiqurasiya simvol adını (məsələn, Objective-C üçün -[UIView layoutSubviews] və ya Swift üçün UIView.layoutSubviews()) və isteğə bağlı parametrləri əhatə edir: modul, şərt və atlama sayı.
// Symbolic breakpoint UITableView-də layoutSubviews-in tutulması üçün
// Simvol adı: -[UITableView layoutSubviews]
// Aksiya: po UITableView.appearance()
class CustomTableView: UITableView {
override func layoutSubviews() {
super.layoutSubviews()
// Symbolic breakpoint burada çağırışı tutacaq
print("layoutSubviews called")
}
}
Şərti breakpoint hər sətrə çatdıqda deyil, yalnız verilmiş məntiqi ifadə true qiyməti aldıqda işləyir. Bu, dövrlərin, massivlərin işlənməsinin və rekursiv çağırışların debugu zamanı böyük vaxt qənaətidir — hər dəfə əl ilə Continue basmaq əvəzinə, proqramçı şərt qoyur və debuger yalnız lazımi anda dayanır.
Şərt əlavə etmək üçün breakpoint üzərində sağ klik edin, Edit Breakpoint seçin və Condition sahəsinə Swift və ya Objective-C ifadəsi daxil edin. Müqayisələr, məntiqi operatorlar və yan təsirləri olmayan metod çağırışlarına icazə verilir. Xcode ifadəni dayandırılmış proqramın kontekstində hesablayır və doğru olarsa, debuger vəziyyəti qeydə alır.
for index in 0..<1000 {
// Şərtli breakpoint: index == 500
// Debuger yalnız 501-ci iterasiyada dayanacaq
processItem(at: index)
}
Şərtdən əlavə, breakpoint proqramı dayandırmadan avtomatik əməliyyatlar yerinə yetirə bilər. Bu, breakpoint parametrlərində Automatically continue after evaluating seçimi ilə həyata keçirilir. Əməliyyatlara daxildir: dəyişənin qiymətini konsola çıxarmaq (po variable), səs siqnalı çalmaq, ixtiyari LLDB əmri yerinə yetirmək və ya shell skripti işə salmaq. Bu yanaşma müvəqqəti print ifadələrini əvəz edir və mənbə kodunu dəyişmədən məlumatların loglanmasına imkan verir.
// Aksiya ilə breakpoint: po "Index: \(index), value: \(items[index])"
// Automatically continue = true → proqram dayanmır
func processItems(_ items: [String]) {
for (index, item) in items.enumerated() {
// Burada breakpoint hər iterasiyanı dayanmadan loglayır
print("Processing \(item)")
}
}
Bu texnika xüsusilə UI yeniləmələrinin debugu zamanı faydalıdır — məsələn, kontrollerin koduna müdaxilə etmədən büt÷n çərçivə dəyişikliklərini loglamaq üçün. Ray Wenderlich-ə görə, müvəqqəti print ifadələri əvəzinə breakpoint əməliyyatlarından istifadə etmək debug vaxtını 30-40% azaldır, çünki iş bitdikdən sonra kodu təmizləməyə ehtiyac qalmır.
Xcode rahat qrafik interfeys təmin etsə də, LLDB debuger konsolundan birbaşa dayanma nöqtələrinin proqram idarə edilməsi üçün onlarla əmr təklif edir. Bu, GUI vasitəsilə mümkün olmayan imkanlar verir: müntəzəm ifadə ilə breakpoint-lərin kütləvi söndürülməsi, dinamik yüklənmiş kitabxanalarda dayanma nöqtələrinin qoyulması və mürəkkəb çoxmərhələli trigger-lərin yaradılması.
| LLDB əmri | Təsvir | Nümunə |
|---|---|---|
| breakpoint set | Breakpoint qoymaq | breakpoint set -f ViewController.swift -l 42 |
| breakpoint list | Bütün breakpoint-ləri göstərmək | breakpoint list |
| breakpoint disable | Breakpoint-i nömrəyə görə söndürmək | breakpoint disable 1 |
| breakpoint delete | Breakpoint-i silmək | breakpoint delete 1.2 |
| breakpoint modify | Şərti və ya əməliyyatı dəyişmək | breakpoint modify -c "i > 100" 1 |
(lldb) breakpoint set -f LoginViewController.swift -l 15 -c "email.isEmpty"
Breakpoint 1: 15 locations added.
(lldb) breakpoint modify 1 -C "po email" -G true
(lldb) breakpoint list
1: name = 'LoginViewController.swift:15', condition = 'email.isEmpty'
1.1: addr = 0x1000a3b40
LLDB funksiya adları üçün müntəzəm ifadə ilə breakpoint qoymağı dəstəkləyir. Bu, naxışa uyğun gələn bütün metodları tutmağa imkan verir — məsələn, müəyyən sinifdə handle ilə başlayan bütün metodlar. Bu yanaşma refaktorinq və tanınmayan kodun təhlili zamanı tətbiq edilir ki, müəyyən hadisənin işlənməsində hansı metodların iştirak etdiyini anlamaq lazım olur.
(lldb) breakpoint set -r "handle[A-Z]" -s DataManager
Breakpoint 2: 6 locations.
(lldb) breakpoint set -r ".*Error.*"
Breakpoint 3: 23 locations.
Exception breakpoint hər hansı istisna atıldıqda proqramın icrasını dayandırır — həm Objective-C, həm də Swift səhvləri. Xcode-da yalnız Objective-C istisnalarının, yalnız Swift səhvlərinin və ya bütün növlərin tutulmasını konfiqurasiya etmək olar. Bu, proqram kodda aşkar yer göstərmədən çökdükdə əvəzolunmaz alətdir — məsələn, artıq azad edilmiş obyektə müraciət edildikdə.
Swift Error Breakpoint — Xcode 11-də ortaya çıxan ixtisaslaşdırılmış növdür. Swift funksiyası throw vasitəsilə səhv atdıqda, həl catch blokuna düşməmişkən həmin anı tutur. Bu, hansı funksiyanın səhvi yaratdığını və hansı arqumentlərlə olduğunu görməyə imkan verir ki, bu da bir neçe səviyyəli səhv idarəetməsi olan mürəkkəb çağırış zəncirinin debugunda kritik əhəmiyyət daşıyır.
enum NetworkError: Error {
case invalidURL
case noData
case decodingFailed(String)
}
func loadUserProfile(id: Int) throws -> UserProfile {
guard id > 0 else {
throw NetworkError.invalidURL
}
// Swift Error Breakpoint throw zamanı burada dayanacaq
return UserProfile(id: id, name: "Test")
}
Simvolik breakpoint-lər KVO və NotificationCenter-in debugunda da effektivdir. observeValue(forKeyPath:of:change:context:) üzrə breakpoint qoyaraq, proqramçı proqramdakı bütün KVO bildirişlərini tuta bilər ki, bu da gözlənilməyən UI yeniləmələrini və ya xüsusiyyətlərin müşahidəsi ilə bağlı race condition-ları diaqnoz etməyə kömək edir.
Breakpoint-lərdən səmərəli istifadə sadəcə sətrdə dayanmaqdan çox daha irəli gedir. Təcrübəli proqramçılar dayanma nöqtələrinin növlərini LLDB skriptləri, müvəqqəti dayanma zonaları və təkrarlana bilən debug üçün konfiqurasiyaların ixracı ilə birləşdirir. Apple və Google mühəndislərinin təcrübəsi ilə təsdiqlənmiş ən faydalı üsulları nəzərdən keçirək.
Çətin tutulan səhvlərin debugu zamanı metoda girişdə breakpoint və açar dəyişənin dəyişməsində watchpoint birləşməsindən istifadə edin. Təyinatdan əvvəl xətti breakpoint qoyun, sonra LLDB watchpoint set variable əmri ilə dəyişən üzərində watchpoint yaradın. Qiymət dəyişdikdə, debuger kodun hansı yerindən dəyişiklik baş verməsindən asılı olmayaraq dayanacaq. Google-a görə, bu yanaşma data race mənbəyini 90% hallarda bir debug sessiyası ərzində tapmağa imkan verir.
(lldb) watchpoint set variable self->_balance
Watchpoint 1: addr = 0x600000c4b80 size = 8
state = enabled type = w
watchpoint spec: 'self._balance'
(lldb) watchpoint list
1: location = 0x600000c4b80, type = write, variable = '_balance'
Xcode Breakpoint Navigator vasitəsilə breakpoint-ləri qruplarda birləşdirməyə imkan verir. Hər ssenari üçün ayrı qrup yaradın — məsələn, «giriş», «alış», «şəbəkə səhvləri». Müəyyən funksionallığı test edərkən, yalnız müvafiq qrupu aktivləşdirin, qalanlarını söndürün. Bu, yalanış işləmələrin qarşısını alır və dayanma nöqtələrinin sayı onlarla ola biləcək böyük layihələrdə debugu sürətləndirir. Qrupun fayla ixracı konfiqurasiyanı versiya nəzarət sistemi vasitəsilə həmkarlarla paylaşmağa imkan verir.
Mürəkkəb ssenarilər üçün LLDB breakpoint işləyərkən Python skriptlərinin yerinə yetirilməsini dəstəkləyir. Breakpoint əməliyyatında script import my_debug_helper; my_debug_helper.log_state() göstərin. Bu, qeyri-məhdud imkanlar açır: statistikaların avtomatik toplanması, çağırışlar arasında vəziyyətlərin müqayisəsi, debug ilə kod əhatəsinin hesabatlarının yaradılması. Apple-a görə, LLDB Python API-si Xcode Cloud-da CI testləri zamanı crash-lərin avtomatik təhlili üçün istifadə olunur.
Tez-tez verilən suallar
Aktiv olmayan breakpoint-lər performansa təsir etmir — onlar yalnız Debug konfiqurasiyasında kompilyasiya olunur. Aktiv dayanma nöqtələri aparat kəsilmə mexanizminə görə icranı yavaşaldır, ancaq yalnız debug vaxtı.
Bəli, metod və ya funksiyanın adı ilə Symbolic breakpoint vasitəsilə. LLDB mənbə kodu əlçatan olmasa belə, simvol çağırıldıqda dayanacaq. Əlavə olaraq addım-addım keçid üçün LLDB dezasemblerindən istifadə etmək olar.
Step Over cari sətri tam yerinə yetirir (funksiya çağırışları daxil olmaqla) və növbəti sətrdə dayanır. Step Into çağırılan funksiyanın içɖrisinə daxil olur, onu addım-addım debug etməyə imkan verir. Step Out idarəni çağıran funksiyaya qaytarır.
Breakpoint-lər avtomatik olaraq layihə daxilində xcuserdata-da saxlanılır. Həmkarlara ötürmək üçün Breakpoint Navigator → Share vasitəsilə ixracdan istifadə edin. .xcbkptlist faylı komanda debugu aparılırsa, depozitariyaya əlavə edilə bilər.
Kompilyasiyanın Debug konfiqurasiyasını, breakpoint-in aktivliyini (göy nişan), symbolic breakpoint üçün simvolun düzgünlüyünü və mənbə kodunun icra olunan binar fayla uyğunluğunu yoxlayın — çox vaxt Clean Build Folder kömək edir.
Nəticə
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