2013-02-12 19 views
5

Giả sử chúng ta có đối tượng khác nhau có cùng tên phương thức nhưng với các loại đối số differet như: getMethod:(NSNumber*)aNumbergetMethod:(NSString*)aString.respondsToSelector với các loại đối số khác nhau trong bộ chọn

Làm thế nào để kiểm tra với respondsToSelector hoặc thông qua cách khác, nếu một đối tượng phản ứng với bộ chọn với kiểu lập luận đặc biệt, một cái gì đó như thế này:

[myObjectA respondsToSelector:@selector(getMethod:(NSNumber*))] 

Làm thế nào để bạn làm điều này? Cảm ơn.

+3

bạn không thể khai báo hai phương thức có cùng tên và các kiểu tham số khác nhau. –

+0

Ok, giả sử chúng ta có các loại đối tượng khác nhau, với cùng tên phương thức, nhưng với các kiểu đối số khác nhau. Những gì bạn làm sau đó? –

+0

bạn sẽ phải sử dụng [Chức năng thời gian chạy mục tiêu-C] (https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/ uid/TP40001418) trực tiếp –

Trả lời

4

Bạn có một vài cách để tìm tên loại đối số cho công cụ chọn. Ví dụ đoạn mã này sẽ làm việc:

Method method = class_getInstanceMethod([self class], @selector(someMethod:param2:param3:)); 
char type[256]; 
int argsNumber = method_getNumberOfArguments(method); 
for (int i = 0; i < argsNumber; i++) { 
    method_getArgumentType(method, i, type, 256); 
    NSLog(@"%s", type); 
} 

Trước lập luận log thứ hai là hệ thống và bạn không quan tâm đến họ, vì vậy một hàng cây là những gì bạn cần.

cũng mã dưới đây sẽ cung cấp cho bạn cùng một kết quả

NSMethodSignature *sig = [self methodSignatureForSelector:@selector(someMethod:param2:param3:)]; 
int args = [sig numberOfArguments]; 
for (int i = 0; i < args; i++) { 
    NSLog(@"%s", [sig getArgumentTypeAtIndex:i]); 
} 

someMethod:param2:param3: có thể thực hiện như thế này ví dụ

- (BOOL) someMethod:(NSString *)str param2:(UIView *)view param3:(NSInteger)number 
{ 
    return NO; 
} 

NHƯNG! Trong nguyên nhân chúng ta có lớn nhưng ở đây)) Trong cả hai trường hợp, bạn sẽ có các kiểu đối số với các chuỗi có kích thước là const char * có độ dài là một biểu tượng. Trình biên dịch mã hóa tên loại như mô tả here. Bạn có thể khác nhau int từ char nhưng không UIView từ NSString. Đối với tất cả các loại id, bạn sẽ có tên loại '@' có nghĩa là nó là id. Đáng buồn nhưng là sự thật. Thật không may tôi đã không tìm thấy bất kỳ cách nào để có được toàn bộ tên đầy đủ hoặc giải mã được đưa ra. Nếu bạn sẽ tìm thấy cách này cho tôi biết xin.

Vì vậy, đây là giải pháp. Hy vọng bạn sẽ tìm ra cách sử dụng cách tiếp cận này trong dự án của bạn.

+0

Cảm ơn bạn Rost!Ngay cả khi câu trả lời của bạn không trực tiếp trả lời cho câu hỏi của tôi, nó giải thích một cách thú vị để làm việc với Runtime. –

+0

Hy vọng Apple sẽ phát hành một phương pháp cho nhu cầu của tôi trong các bản phát hành tính năng của SDK. –

+0

Chắc chắn rằng họ sẽ vì nhu cầu của bạn đi ngược lại triết lý của họ về việc đặt tên tiết. Đề nghị của tôi là chỉ đơn giản là refactor để họ có tên mà thực sự chỉ ra những gì họ đang làm. Thậm chí nếu nó đơn giản như 'getMethodFromNumber:' hay 'getMethodFromString:' – borrrden

0

Bạn sẽ không thực sự có thể phân biệt các loại phương pháp tham số nhưng có lẽ bạn có thể làm một cái gì đó như thế này thay vì:

if([myObject isKindOfClass:[A class]]) 
    [myObjectA getMethod:aNumber]; 
else if([myObject isKindOfClass:[B class]]) 
    [myObjectA getMethod:aString]; 

Bạn sẽ không cần phải kiểm tra xem nó phản ứng với bộ chọn kể từ khi bạn đã kiểm tra rằng nó là đúng loại. Có lẽ vấn đề của bạn phức tạp hơn điều này nhưng điều này sẽ hoạt động nếu không.

+0

Thực ra nó không phải là luồng công việc mong muốn cho trường hợp của tôi. –

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