Kiểm tra xem một phương pháp có tồn tại không


110

Có cách nào tôi có thể kiểm tra xem một phương thức tồn tại trong Objective-C không?

Tôi đang cố gắng thêm một trình bảo vệ để xem liệu đối tượng của tôi có phương thức hay không trước khi gọi nó.


Cũng có một câu hỏi đặt ra là liệu đây có phải là cách tiếp cận đúng ngay từ đầu hay không, vì các lớp Objective-C có thể phản hồi các bộ chọn mà chúng chưa khai báo (thông qua - forwardInvocation:).
Donal Fellows

Câu trả lời:


189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

72

Ngoài ra còn có bộ chọn tin nhắn tĩnh instanceRespondToSelector: (SEL) Bạn sẽ gọi nó như thế này:

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

hoặc như thế này:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

Điều này có thể hữu ích nếu bạn muốn gọi một hàm tạo hoặc một hàm tạo khác tùy thuộc vào điều này (ý tôi là, trước khi có chính thể hiện).


1
Điều gì khác biệt của instanceRespondToSelector với responseToSelector?
CReaTuS

1
Sự khác biệt chính là một là một thông điệp cá thể (để kiểm tra xem một thông điệp cá thể xác định có tồn tại hay không) trong khi cái kia là một thông điệp lớp (để kiểm tra xem một thông điệp lớp xác định có tồn tại hay không).
Ricard Pérez del Campo

1
+1 Đối với [MyClass instanceRespondToSelector]. Tôi cần nó bên trong một phương thức tạo init: Khi phân lớp có thể cần thiết phải gọi một phương thức super init thay vì các phương thức khác (những phương thức không được dùng nữa), vì bản thân chưa được tạo và responseToSelector sẽ luôn trả về NO.
LightMan

12

Sử dụng respondsToSelector:. Từ tài liệu :

responseToSelector:

Trả về một giá trị Boolean cho biết liệu người nhận có triển khai hay kế thừa một phương thức có thể phản hồi một thông báo được chỉ định hay không.

- (BOOL)respondsToSelector:(SEL)aSelector

Tham số
aSelector - Một bộ chọn xác định một tin nhắn.

Trả về Giá trị
YES nếu người nhận triển khai hoặc kế thừa một phương thức có thể phản hồi với aSelector , ngược lại NO.


10

Bạn đang tìm kiếm responseToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

Như Donal đã nói ở trên cho bạn biết rằng foo chắc chắn có thể xử lý việc nhận bộ chọn thanh. Tuy nhiên, nếu một proxy của foo chuyển tiếp thanh tới một số đối tượng bên dưới sẽ nhận được thông báo trên thanh, thì responseToSelector: sẽ cho bạn biết KHÔNG, mặc dù thông báo sẽ được chuyển tiếp đến một đối tượng phản hồi với thanh.


1

Việc kiểm tra các bộ chọn với responseToSelector thường chỉ dành cho các phương thức ủy quyền. Bạn không nên sử dụng forwardInvocation hoặc proxy cho các phương thức ủy quyền. Nếu bạn cần sử dụng responseToSelector trong các tình huống khác, bạn có thể muốn đảm bảo rằng không có cách nào thích hợp hơn để thiết kế chương trình của bạn.

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.