2008-11-18 26 views
53

Tôi có một mẫu mã mà được một SEL từ đối tượng hiện tại,Tạo một chọn từ một tên phương pháp với các thông số

SEL callback = @selector(mymethod:parameter2); 

Và tôi có một phương pháp như

-(void)mymethod:(id)v1 parameter2;(NSString*)v2 { 
} 

Bây giờ tôi cần phải di chuyển mymethod đến một đối tượng khác, giả sử myDelegate.

Tôi đã thử:

SEL callback = @selector(myDelegate, mymethod:parameter2); 

nhưng nó sẽ không biên dịch.

+2

@Jim Puls - đây thực sự là một vấn đề Objective-C ... nó không cụ thể hơn cho Cocoa hoặc Cocoa-touch so với iPhone-sdk. Ngoài ra, chúng tôi đang đi với thẻ mục tiêu-c trên objectivec những ngày này :) –

Trả lời

95

SEL là loại đại diện cho bộ chọn trong Mục tiêu-C. Từ khóa @selector() trả về SEL mà bạn mô tả. Nó không phải là một con trỏ hàm và bạn không thể vượt qua nó bất kỳ đối tượng hoặc tài liệu tham khảo dưới bất kỳ hình thức nào. Đối với mỗi biến trong bộ chọn (phương thức), bạn phải biểu diễn điều đó trong lời gọi đến @selector. Ví dụ:

-(void)methodWithNoParameters; 
SEL noParameterSelector = @selector(methodWithNoParameters); 

-(void)methodWithOneParameter:(id)parameter; 
SEL oneParameterSelector = @selector(methodWithOneParameter:); // notice the colon here 

-(void)methodWIthTwoParameters:(id)parameterOne and:(id)parameterTwo; 
SEL twoParameterSelector = @selector(methodWithTwoParameters:and:); // notice the parameter names are omitted 

Bộ chọn thường được chuyển đến phương thức đại biểu và gọi lại để chỉ định phương thức nên được gọi trên một đối tượng cụ thể trong khi gọi lại. Ví dụ, khi bạn tạo một bộ đếm thời gian, phương pháp gọi lại được xác định cụ thể như:

-(void)someMethod:(NSTimer*)timer; 

Vì vậy, khi bạn lên lịch hẹn giờ bạn sẽ sử dụng @selector để xác định các phương pháp trên đối tượng của bạn sẽ thực sự chịu trách nhiệm về callback:

@implementation MyObject 

-(void)myTimerCallback:(NSTimer*)timer 
{ 
    // do some computations 
    if(timerShouldEnd) { 
     [timer invalidate]; 
    } 
} 

@end 

// ... 

int main(int argc, const char **argv) 
{ 
    // do setup stuff 
    MyObject* obj = [[MyObject alloc] init]; 
    SEL mySelector = @selector(myTimerCallback:); 
    [NSTimer scheduledTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES]; 
    // do some tear-down 
    return 0; 
} 

Trong trường hợp này, bạn xác định rằng đối tượng obj được nhắn tin với myTimerCallback sau mỗi 30 giây.

+1

coco - bạn có thể cung cấp mã mà NSTimer đang thực hiện để gọi bộ chọn mà nó đã nhận không? – mobibob

16

Bạn không thể chuyển tham số trong @selector().

Dường như bạn đang cố thực hiện gọi lại. Cách tốt nhất để làm điều đó sẽ là một cái gì đó như thế này:

[object setCallbackObject:self withSelector:@selector(myMethod:)]; 

Sau đó, trong đối tượng của bạn setCallbackObject: withSelector: Phương pháp: bạn có thể gọi phương thức callback của bạn.

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector { 
    [anObject performSelector:selector]; 
} 
+0

Điều này không hoàn toàn là iPhone. Bạn có thể muốn đọc tài liệu của Apple "Ngôn ngữ lập trình Obective-C 2.0" có thể tìm thấy tại đây http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html –

+4

Để gọi bộ chọn bạn cần gọi: [anObject performSelector: selector]; –

5

Ngoài những gì đã được nói về các bộ chọn, bạn có thể muốn xem lớp NSInvocation.

An NSInvocation là thông điệp mục tiêu-C được hiển thị tĩnh, tức là, nó là một hành động được chuyển thành đối tượng. Các đối tượng NSInvocation được sử dụng để lưu trữ và chuyển tiếp các thông điệp giữa các đối tượng và giữa các ứng dụng, chủ yếu bởi các đối tượng NSTimer và hệ thống đối tượng phân tán.

Đối tượng NSInvocation chứa tất cả các phần tử của thông điệp Mục tiêu-C: mục tiêu, công cụ chọn, đối số và giá trị trả lại. Mỗi phần tử này có thể được đặt trực tiếp và giá trị trả lại được đặt tự động khi đối tượng NSInvocation được gửi đi.

Hãy nhớ rằng mặc dù nó hữu ích trong một số trường hợp nhất định, bạn không sử dụng NSInvocation trong một ngày bình thường mã hóa.Nếu bạn đang cố gắng để có được hai đối tượng để nói chuyện với nhau, hãy xem xét xác định một giao thức đại biểu chính thức hoặc không chính thức, hoặc đi qua một bộ chọn và đối tượng đích như đã được đề cập.

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