Làm cách nào để đặt một điểm ngắt có điều kiện trong Xcode dựa trên thuộc tính chuỗi đối tượng?


90

Tôi đang tìm cách có thể ngắt trình gỡ lỗi khi nó đạt đến một chuỗi cụ thể phù hợp. Ví dụ, tôi có thể có một cái gì đó như thế này:

Foo myObj = [self gimmeObj];

myObjcó thể có một thuộc tính được gọi name. Tôi muốn trình gỡ lỗi ngừng thực hiện nhiệm vụ khi

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

Làm cách nào để đặt điểm ngắt có điều kiện trong Xcode để thực hiện điều đó?

Câu trả lời:


184

Bạn có thể đặt điểm ngắt có điều kiện trong Xcode bằng cách đặt điểm ngắt bình thường, sau đó giữ phím điều khiển và nhấp vào điểm đó và chọn Chỉnh sửa điểm ngắt (chọn Chạy -> Hiển thị -> Điểm ngắt).

Trong mục điểm ngắt, có cột Điều kiện.

Bây giờ, có một số vấn đề cần lưu ý đối với tình trạng này. Thứ nhất, gdb không hiểu cú pháp dấu chấm, vì vậy thay vì myObj.name, bạn phải sử dụng [myObj name] (trừ khi tên là ivar).

Tiếp theo, như với hầu hết các biểu thức trong gdb, bạn phải cho nó biết loại kết quả trả về, cụ thể là "BOOL". Vì vậy, hãy đặt một điều kiện như:

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

Thường thì thực sự dễ dàng hơn nếu chỉ làm điều này trong mã bằng cách tạm thời thêm mã như:

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

và sau đó đặt điểm ngắt trên NSLog. Sau đó, tình trạng của bạn có thể phức tạp tùy ý mà không cần phải lo lắng về những gì gdb có thể và không thể phân tích cú pháp.


11
Ngoại trừ việc bằng cách thay đổi mã của bạn, bạn có nguy cơ quên xóa hành vi ghi nhật ký hoặc thay đổi hành vi của mình
Pål Brattberg

3
Đúng. Tôi thường giảm thiểu điều này bằng cách thêm "NYI" (Chưa được triển khai) vào chuỗi và sau đó tìm kiếm séc trước khi phát hành cho NYI của tôi sẽ bắt được nó.
Peter N Lewis

17
Để làm được điều này, tôi phải viết hoa (bool) thành (BOOL), có lẽ là một thứ LLDB.
Wex

1
bool không hoạt động với tôi trong GDB, tôi phải sử dụng BOOL hoặc int– sự khác biệt được giải thích ở đây stackoverflow.com/a/544250/725871 .
Chaosphere2112,

2
Bạn không thể đưa nó vào mã nếu bạn có một lần trong 200 lỗi trò chơi cuối cùng đã xuất hiện và bây giờ bạn cần thực hiện một điểm ngắt có điều kiện. Dừng chương trình để thay đổi mã không phải là một tùy chọn.
Almo

17

Đây là cách bạn thực hiện bằng cách sử dụng các điểm ngắt có điều kiện XCode lldb.

Đầu tiên, nhấp đúp vào điểm ngắt (hoặc nhấp chuột phải edit breakpoint), bạn có thể thấy một hộp thoại bật lên.

nhập mô tả hình ảnh ở đây

Đây là ý nghĩa của tùy chọn đó:

  1. Điều kiện : Điểm ngắt sẽ chỉ hoạt động trong điều kiện này.
  2. Bỏ qua : Số lần điều kiện cần đáp ứng trước khi kích hoạt điểm ngắt
  3. Hành động : Hành động chạy sau khi ngắt điểm ngắt.
  4. Tùy chọn : Tự động tiếp tục sau khi đánh giá các hành động

Đây là một bản tóm tắt. Đối với ví dụ trên trong hình ảnh, điều đó có nghĩa là khi biếnbuildingId bằng 13, ngắt ở đây. Nếu tôi thêm thời gian bỏ qua vào 1, thì nó sẽ bỏ qua lần đầu tiên khi buildingIdbằng 13 và ngắt ở lần thứ hai đáp ứng điều kiện.

Đối với hành động, khi bạn nhấn thêm hành động, sẽ có một danh sách lựa chọn. Thông thường những gì tôi làm là sử dụng các Debugger Command pobiến để in mà tôi cần kiểm tra và tôi tin rằng có nhiều cách tốt hơn bằng cách sử dụng các hành động sau đó tôi làm.

Có vẻ như bạn phải biên dịch lại và chạy ứng dụng nếu bạn thay đổi các điều kiện trong thời gian chạy


Có lẽ vì câu hỏi về việc dừng lại ở điểm ngắt dựa trên giá trị chuỗi [Tôi không phải là người bỏ phiếu]
ZS

1
Cảm ơn, khá hữu ích. Câu trả lời này xứng đáng được bình chọn nhiều hơn.
andreskwan

7

Tôi không chắc liệu điều này có hoạt động hay không, nhưng bạn có thể thử đặt một điểm ngắt tại dòng mã đó, mở bảng điều khiển trình gỡ lỗi (Cmd + Shift + R) và nhập

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

Trong đó N được thay thế bằng số điểm ngắt (một số nguyên).


2

Nếu bạn thay đổi myObj.name bằng cách sử dụng setter, bạn có thể thêm một điểm ngắt tượng trưng trên -[MyObjClass setName:]Bảng điều khiển gỡ lỗi hoặc từ menu Run-> Manage Breakpoints-> Add Symbolic Breakpoint trong Xcode. Nếu không (tại sao không? Có lẽ bạn không nên sửa đổi trực tiếp biến cá thể ngoại trừ trong trình khởi tạo hoặc dealloc được chỉ định), bạn có thể đặt một điểm giám sát trong gdb (sử dụng Bảng điều khiển gỡ lỗi trong Xcode khi trình gỡ lỗi đang chạy). Đây trang giải thích như thế nào. Tôi không tin rằng Xcode có giao diện người dùng để thiết lập các điểm theo dõi mà không sử dụng Bảng điều khiển gỡ lỗi.


0

Đôi khi khi làm việc với Framework (bản dựng gỡ lỗi) và cần đặt một điểm dừng ở một tệp / vị trí nhất định khó điều hướng hoặc không được hiển thị công khai trong khuôn khổ đang phát triển. Một tùy chọn là viết một lớp trợ giúp để kích hoạt các điểm ngắt có điều kiện và giúp bước vào / bước ra dễ dàng hơn.

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

Khai báo tiêu đề trong khuôn khổ đang được phát triển.

#import <Foundation/Foundation.h>

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

Và tệp thực hiện:

#import "DebugConditionalBreakPointHelper.h"

@implementation DebugConditionalBreakPointHelper
+ (void)breakPointCondition:(BOOL)enabled comment:(NSString *)comment {
    if (enabled)
    {
        NSLog(@"Triggerred Conditional Break Point. Comment: %@");
    }
}
@end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.