2009-06-19 27 views
135

Trong MyClass.m, tôi đã xác địnhObjective-C: Gọi selectors với nhiều đối số

- (void) myTest: (NSString *) withAString{ 
    NSLog(@"hi, %@", withAString); 
} 

và tuyên bố thích hợp trong MyClass.h. Sau đó tôi muốn gọi

[self performSelector:@selector(mytest:withAString:) withObject: mystring]; 

trong MyClass.m nhưng tôi nhận được một lỗi tương tự như * Chấm dứt ứng dụng do ngoại lệ còn tự do 'NSInvalidArgumentException', lý do: '* - [MyClass MyTest: withAtring:]: bộ chọn không được nhận dạng được gửi tới ví dụ 0xe421f0 '

Tôi đã thử một trường hợp đơn giản hơn với bộ chọn không lấy đối số nào đã in chuỗi để điều khiển và hoạt động tốt. Có gì sai với mã và làm thế nào tôi có thể sửa nó? Cảm ơn.

+4

Bài đăng của bạn hỏi về 'nhiều đối số', nhưng bạn chỉ sử dụng một đối số. Bây giờ tôi tò mò về làm thế nào một người nào đó làm điều đó với nhiều đối số, khác hơn là gói chúng trong một mảng/dict/bất cứ điều gì. – RonLugge

Trả lời

130

phương pháp chữ ký của bạn là:

- (void) myTest:(NSString *) 

withAString sẽ xảy ra là các tham số (tên là lừa dối, có vẻ như nó là một phần của chữ ký của selector).

Nếu bạn gọi hàm theo cách này:

[self performSelector:@selector(myTest:) withObject:myString]; 

Nó sẽ làm việc.

Nhưng, như các áp phích khác đã gợi ý, bạn có thể muốn đổi tên phương pháp:

- (void)myTestWithAString:(NSString*)aString; 

Và gọi:

[self performSelector:@selector(myTestWithAString:) withObject:myString]; 
+1

Cảm ơn! Chỉnh sửa nhỏ. Chữ "t" trong "mytest:" phải được viết hoa thành "T". self performSelector: @selector (mytest :) withObject: myString]; – Stu

+0

Cảm ơn, đã cập nhật bài đăng của tôi :) –

+1

Bây giờ tôi thấy mọi người đã được hưởng lợi từ câu trả lời này, tôi đã xem xét phản hồi của mình; Tôi sẽ đề nghị rằng cuộc gọi chỉ đơn giản là: - (void) testWithString: (NSString *) aString; –

2

Nghĩ lớp nên được định nghĩa là:

- (void) myTestWithSomeString:(NSString *) astring{ 
    NSLog(@"hi, %s", astring); 
} 

Bạn chỉ có một tham số duy nhất, do đó bạn chỉ nên có một duy nhất:

Bạn có thể muốn xem xét sử dụng% @ trong NSLog của bạn cũng - nó chỉ là một thói quen tốt để đi vào - sau đó sẽ viết ra bất kỳ đối tượng nào - không chỉ là chuỗi.

3

Chữ ký phương thức của bạn không có ý nghĩa gì cả, bạn có chắc đó không phải là lỗi đánh máy? Tôi không rõ làm thế nào nó thậm chí biên dịch, mặc dù có lẽ bạn đang nhận được cảnh báo rằng bạn đang bỏ qua?

Bạn dự kiến ​​có bao nhiêu tham số này?

+0

Xin lỗi bạn đang viết. Tôi đã gõ nó ra và cố gắng làm cho nó đơn giản hơn thay vì sao chép và dán mã của tôi nhưng tôi đã mắc lỗi trong quá trình này. Tôi đang mong đợi phương pháp này để lấy một tham số; chuỗi tôi muốn in. – Stu

297

Trong Objective-C, chữ ký của một selector gồm:

  1. Tên của phương pháp (trong trường hợp này sẽ là 'myTest') (bắt buộc)
  2. Dấu ':' (dấu hai chấm) theo tên phương thức nếu phương thức có đầu vào.
  3. Tên và ':' cho mọi đầu vào bổ sung.

Selectors không có kiến ​​thức về:

  1. Các loại đầu vào
  2. kiểu trả về Phương pháp của.

Dưới đây là một việc thực hiện lớp mà phương pháp performMethodsViaSelectors thực hiện các phương thức lớp khác bằng cách selectors:

@implementation ClassForSelectors 
- (void) fooNoInputs { 
    NSLog(@"Does nothing"); 
} 
- (void) fooOneIput:(NSString*) first { 
    NSLog(@"Logs %@", first); 
} 
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second { 
    NSLog(@"Logs %@ then %@", first, second); 
} 
- (void) performMethodsViaSelectors { 
    [self performSelector:@selector(fooNoInputs)]; 
    [self performSelector:@selector(fooOneInput:) withObject:@"first"]; 
    [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"]; 
} 
@end 

Phương pháp bạn muốn tạo một selector cho có một đầu vào duy nhất, do đó bạn sẽ tạo ra một selector cho nó như vậy:

SEL myTestSelector = @selector(myTest:); 
+3

Câu trả lời hay. Để làm rõ một chút, bạn chọn tên bộ chọn PHẢI có ít nhất một phần, có thể hoặc không thể tham số - nếu có, nó phải có dấu hai chấm. Tên bộ chọn có hai hoặc nhiều phần PHẢI có dấu hai chấm sau phần M EI - không hợp pháp để có bộ chọn dạng "-useFoo: andBar: toDoSomething". –

+0

cảm ơn vì điều này. ive đã đấu tranh với điều này trong một thời gian, vui mừng vì sự giúp đỡ! –

+0

làm thế nào về các tham số đầu vào là số nguyên? phải làm gì trong trường hợp này? –

7

Mã của bạn có hai vấn đề. Một đã được xác định và trả lời, nhưng người kia thì không. Đầu tiên là bộ chọn của bạn thiếu tên tham số của nó. Tuy nhiên, ngay cả khi bạn khắc phục điều đó, dòng vẫn sẽ tăng ngoại lệ, giả sử chữ ký phương thức đã sửa đổi của bạn vẫn bao gồm nhiều hơn một đối số. Giả sử phương pháp được sửa đổi của bạn được khai báo là:

-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ; 

Tạo bộ chọn cho nhiều phương pháp có nhiều đối số là hoàn toàn hợp lệ (ví dụ: @selector (myTestWithString: compareTo :)). Tuy nhiên, phương thức performSelector chỉ cho phép bạn chuyển một giá trị cho myTest, mà không may có nhiều tham số. Nó sẽ lỗi và cho bạn biết rằng bạn không cung cấp đủ giá trị.

Bạn luôn có thể xác định lại phương pháp của bạn để có một bộ sưu tập như nó chỉ tham số:

-(void)myTestWithObjects:(NSDictionary *)testObjects ; 

Tuy nhiên, có một giải pháp thanh lịch hơn (mà không yêu cầu tái cấu trúc). Câu trả lời là sử dụng NSInvocation, cùng với các phương thức setArgument:atIndex:invoke của chúng tôi.

Tôi đã viết lên an article, including a code example, nếu bạn muốn biết thêm chi tiết. Trọng tâm là trên luồng, nhưng những điều cơ bản vẫn được áp dụng.

Chúc may mắn!

13

@Shane Arney

performSelector:withObject:withObject: 

Bạn cũng có thể muốn đề cập đến rằng phương pháp này chỉ dành cho đi qua tối đa 2 đối số, và nó không thể trì hoãn. (Chẳng hạn như performSelector:withObject:afterDelay:)

kinda lạ đó táo chỉ hỗ trợ 2 đối tượng được gửi và didnt làm cho nó chung chung hơn

+2

Cảm ơn thông tin. Tôi không thể có được sự chậm trễ để làm việc và bây giờ tôi biết tại sao. FYI, để vượt qua giới hạn của hai đối tượng, tôi đã vượt qua một mảng và sau đó sử dụng nó trong phương thức. – JScarry

0

người dùng iOS cũng mong đợi autocapitalization:.. Trong một lĩnh vực văn bản chuẩn, chữ cái đầu tiên của một câu trong một ngôn ngữ case-sensitive là tự động viết hoa

Bạn có thể quyết định có hay không để thực hiện các tính năng như;. không có API dành riêng cho bất kỳ tính năng chỉ niêm yết, do đó cung cấp cho họ là một lợi thế cạnh tranh .

Tài liệu Apple cho biết không có sẵn API cho tính năng này và một số tính năng được mong đợi khác trong bảng tùy chỉnh. vì vậy bạn cần phải tìm ra logic của riêng bạn để thực hiện điều này.

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