2009-11-23 44 views
41

Giả sử tôi đã Objective C giao diện SomeClass trong đó có một phương pháp lớp được gọi là someMethod:động gọi một phương thức lớp trong Objective C

@interface SomeClass : NSObject { 
} 

+ (id)someMethod; 
@end 

Trong một số giao diện khác mà tôi muốn có một phương pháp helper rằng động sẽ gọi someMethod trên một lớp học như thế này:

[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class]; 

Việc triển khai thực hiện cho invokeSelector là gì? Có thể ở tất cả?

- (void)invokeSelector:(SEL)aSelector forClass:(Class)aClass { 
    // ??? 
} 
+1

Trong mã ví dụ của bạn, bạn khai báo SomeClass làm lớp gốc. Có rất hiếm khi cần thiết cho việc này. Nó chỉ là một sai lầm trong câu hỏi của bạn? –

+1

Có. Đó là một sai lầm. Cảm ơn bạn đã chỉ ra điều đó. – GregK

Trả lời

83

Thay vì:

[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class]; 

gọi:

[[SomeClass class] performSelector:@selector(someMethod)]; 

Ví dụ (sử dụng GNUstep ...)

tập Ah

#import <Foundation/Foundation.h> 
@interface A : NSObject {} 

- (NSString *)description; 
+ (NSString *)action; 
@end 

tập tin giờ sáng

#import <Foundation/Foundation.h> 
#import "A.h" 

@implementation A 

- (NSString *)description 
{ 
    return [NSString stringWithString: @"A"]; 
} 

+ (NSString *)action 
{ 
    return [NSString stringWithString:@"A::action"]; 
} 

@end 

Một nơi nào đó khác:

A *a = [[A class] performSelector:@selector(action)]; 
NSLog(@"%@",a); 

Output:

2009-11-22 23:32:41.974 abc[3200] A::action 

đẹp giải thích từ http://www.cocoabuilder.com/archive/cocoa/197631-how-do-classes-respond-to-performselector.html:

"Trong mục tiêu-C, một đối tượng lớp nhận tất cả các phương thức thể hiện của lớp gốc cho phân cấp của nó. Điều này có nghĩa rằng tất cả các đối tượng lớp mà xuống từ NSObject được tất cả các phương pháp dụ NSObject của -. bao gồm performSelector :."

+0

Tôi biết tôi có thể sử dụng performSelector trên NSObject. Tuy nhiên, tôi đã nhầm lẫn bởi vì tôi nghĩ loại Class không có phương thức performSelector. Tôi không bận tâm. – GregK

+10

Mã Sense không đề xuất 'performSelector' cho' [SomeClass class] 'experssion. – GregK

+0

Tôi không ở phía trước máy Mac, vì vậy tôi đã thử trên Linux với GNUStep và nó hoạt động ... :) – stefanB

2

Bạn không nên tự thực hiện việc này.

Giao thức NSObject có phương thức performSelector: thực hiện chính xác việc này.

+3

Loại Lớp không phải là NSObject. Nó không có phương thức performSelector – GregK

+0

Các đối tượng 'Class' có thực thi giao thức' NSObject' không? – mipadi

+0

Bạn tạo một đối tượng không phải là NSObject như thế nào? Từ đầu trang của liên kết tôi đưa ra: "Giao thức NSObject nhóm các phương thức cơ bản cho tất cả các đối tượng Objective-C". –

1

Phương pháp này có được xây dựng trong những gì bạn muốn không?

id objc_msgSend(id theReceiver, SEL theSelector, ...) 

(Xem runtime reference docs for this function.)

+0

Từ liên kết của bạn: "Tham chiếu này hữu ích cho việc phát triển các lớp cầu nối giữa Objective-C và các ngôn ngữ khác, hoặc để gỡ lỗi ở mức độ thấp. Bạn thường không cần phải sử dụng thư viện runtime Objective-C trực tiếp khi lập trình trong Objective-C. " –

+0

Nhưng không phải là tránh kiểm tra tích hợp và cân bằng toàn bộ các điểm gửi tin nhắn động? –

+0

Đừng bận tâm; đã không nhận thấy rằng nó không phải là một phân lớp của NSObject. –

4

Trong Objective-C, lớp học được đối tượng cũng Các đối tượng lớp được đối xử khác nhau, tuy nhiên, như họ . có thể gọi các phương pháp thể hiện của lớp học của họ root (NSObject hoặc NSProxy trong Cocoa)

vì vậy, nó có thể sử dụng tất cả các phương pháp dụ quy định tại NSObject trên các đối tượng lớp là tốt và đúng cách để tự động gọi một phương thức lớp là:

[aClass performSelector:@selector(aSelector)]; 

apple docs cụ thể hơn một chút.

Các vấn đề liên quan