Bagaimana cara mengatur breakpoint bersyarat di Xcode berdasarkan properti string objek?

93

Saya mencari untuk dapat memiliki debugger istirahat ketika mencapai kecocokan string tertentu. Sebagai contoh, saya mungkin memiliki sesuatu seperti ini:

Foo myObj = [self gimmeObj];

myObjmungkin memiliki properti bernama name. Saya ingin debugger menghentikan tugas ketika

[myObj.name isEqualToString:@"Bar"];

Bagaimana cara mengatur breakpoint bersyarat saya di Xcode untuk melakukan itu?

Coocoo4Cocoa
sumber

Jawaban:

184

Anda dapat mengatur break point bersyarat di Xcode dengan mengatur breakpoint secara normal, kemudian control-klik di atasnya dan pilih Edit Breakpoint (pilih Run -> Show -> Breakpoints).

Di entri breakpoint, ada kolom Kondisi.

Nah, ada beberapa hal yang perlu diperhatikan untuk kondisi tersebut. Pertama, gdb tidak memahami sintaks titik, jadi alih-alih myObj.name, Anda harus menggunakan [nama myObj] (kecuali nama adalah ivar).

Selanjutnya, seperti kebanyakan ekspresi di gdb, Anda harus memberitahukan jenis hasil yang dikembalikan, yaitu "BOOL". Jadi tetapkan kondisi seperti:

(BOOL)[[myObj name] isEqualToString:@"Bar"]

Seringkali sebenarnya lebih mudah untuk melakukan ini dalam kode dengan menambahkan kode sementara seperti:

if ( [myObj.name isEqualToString:@"Bar"] ) {
    NSLog( @"here" );
}

dan kemudian mengatur break point pada NSLog. Kemudian kondisi Anda dapat menjadi sangat kompleks tanpa harus khawatir tentang apa yang dapat dan tidak dapat diurai oleh gdb.

Peter N Lewis
sumber
12
Kecuali bahwa dengan mengubah kode Anda, Anda berisiko lupa untuk menghapus logging atau mengubah perilaku
Pål Brattberg
3
Itu benar. Saya sering mengurangi ini dengan menambahkan "NYI" (Belum Diimplementasikan) ke string, dan kemudian pencarian cek pra-rilis saya untuk NYI akan menangkapnya.
Peter N Lewis
18
Untuk mendapatkan ini bekerja saya harus membuat (bool) huruf besar sebagai (BOOL), mungkin sebuah LLDB.
Wex
1
bool tidak bekerja untuk saya di GDB, saya harus menggunakan BOOL atau int– perbedaannya dijelaskan di sini stackoverflow.com/a/544250/725871 .
Chaosphere2112
2
Anda tidak dapat memasukkannya ke dalam kode jika Anda memiliki bug setiap 200 game yang akhirnya muncul, dan sekarang Anda perlu melakukan breakpoint bersyarat. Menghentikan program untuk mengubah kode bukanlah suatu pilihan.
Almo
21

Berikut adalah cara Anda menggunakan breakpoint bersyarat XCode lldb.

Pertama, klik dua kali break point (atau klik kanan edit breakpoint), Anda dapat melihat popup dialog.

masukkan deskripsi gambar di sini

Inilah arti dari opsi tersebut:

  1. Kondisi : Breakpoint hanya akan aktif dalam kondisi ini.
  2. Abaikan : Berapa kali kondisi harus dipenuhi sebelum mengaktifkan breakpoint
  3. Tindakan : Tindakan yang dijalankan setelah breakpoint putus.
  4. Opsi : Secara otomatis melanjutkan setelah mengevaluasi tindakan

Berikut ringkasannya. Untuk contoh gambar di atas, itu berarti bahwa ketika variabel buildingIdsama dengan 13, pecahkan di sini. Jika saya menambahkan waktu pengabaian ke 1, maka waktu pengabaian pertama akan diabaikan jika buildingIdsama dengan 13 dan istirahat di saat kedua kondisi terpenuhi.

Untuk tindakan, saat Anda menekan tambahkan tindakan, akan ada daftar pilihan. Biasanya yang saya lakukan adalah menggunakan Debugger Command pountuk mencetak variabel yang perlu saya periksa dan saya yakin ada cara yang lebih baik menggunakan tindakan daripada yang saya lakukan.

Tampaknya Anda harus mengompilasi ulang dan menjalankan aplikasi jika Anda mengubah kondisi saat runtime

nuynait
sumber
Mungkin karena pertanyaannya adalah tentang berhenti di breakpoint berdasarkan nilai string [saya bukan pemilih bawah]
ZS
1
Terima kasih, cukup membantu. Jawaban ini membutuhkan lebih banyak suara.
andreskwan
7

Saya tidak yakin apakah ini akan berhasil, tetapi Anda dapat mencoba mengatur breakpoint pada baris kode itu, buka konsol debugger (Cmd + Shift + R), dan ketik

condition N (int)[[myObj name] isEqualToString:@"Bar"]

Dimana N diganti dengan jumlah breakpoint (integer).

Adam Rosenfield
sumber
2

Jika Anda memutasi myObj.name menggunakan setter, Anda dapat menambahkan breakpoint simbolis -[MyObjClass setName:]baik dari Debugger Console atau dari Run-> Manage Breakpoints-> Add Symbolic Breakpoint menu di Xcode. Jika tidak (mengapa tidak? Anda mungkin tidak boleh memodifikasi variabel instance secara langsung kecuali di penginisialisasi atau dealloc yang ditentukan), Anda dapat menyetel watchpoint di gdb (gunakan Konsol Debugger di Xcode setelah debugger berjalan). Halaman ini menjelaskan caranya. Saya tidak percaya Xcode mengekspos UI untuk mengatur watchpoints tanpa menggunakan Debugger Console.

Barry Wark
sumber
0

Saat bekerja dengan Frameworks (debug builds) dan perlu meletakkan breakpoint di file / lokasi tertentu yang sulit dinavigasi atau tidak diekspos secara publik dalam framework yang sedang dikembangkan. Salah satu opsinya adalah menulis kelas pembantu untuk memicu breakpoint bersyarat & membuat langkah-masuk / keluar lebih mudah.

- (void)invokeFrameworkMethod {
    ...
    [DebugConditionalBreakPointHelper breakPointCondition:YES comment:@"from invokeFrameworkMethod."];
    ...
}

Deklarasi header dalam kerangka kerja yang sedang dikembangkan.

#import <Foundation/Foundation.h>

@interface DebugConditionalBreakPointHelper : NSObject
+ (void)breakPointCondition:(BOOL)enabled comment:(NSString *)comment;
@end

Dan file implementasi:

#import "DebugConditionalBreakPointHelper.h"

@implementation DebugConditionalBreakPointHelper
+ (void)breakPointCondition:(BOOL)enabled comment:(NSString *)comment {
    if (enabled)
    {
        NSLog(@"Triggerred Conditional Break Point. Comment: %@");
    }
}
@end
lal
sumber