2011-08-17 43 views
7

Đôi khi tôi muốn tổ chức các yếu tố IB thành NSArray s chủ yếu để giúp tôi tổ chức các yếu tố của mình. Thông thường, các lớp đối tượng khác nhau biến nó thành cùng một mảng với nhau. Trong khi điều này một cách thuận tiện để tổ chức, tôi dường như không thể quấn quanh đầu tôi lý do tại sao nếu tôi có một mảng như thế này:cho vòng lặp - Loại đối tượng bị bỏ qua?

NSArray *array = [NSArray arrayWithObjects:((UITextField *)textField), ((UISegmentedController *)segmentedController), nil]; 

Tại sao tôi nhận được "Không đáp ứng với Selector" thông điệp khi tôi đặt một vòng lặp for như thế này:

for (UITextField *text in array) { 
    [text setText:@""]; 
} 

vòng lặp for dường như được thông qua đối tượng mà không phải là của lớp UITextField.

Điểm khai báo lớp của đối tượng là gì nếu tất cả các đối tượng trong mảng được chỉ định được truyền qua vòng lặp?

EDIT Chỉ cần để tham khảo, đây là cách tôi đang xử lý nó như bây giờ:

for (id *object in array) { 
    if ([object isMemberOfClass:[UITextField class]]) { 
     foo(); 
    } else if ([object isMemberOfClass:[UISegmentedController class]) { 
     bar(); 
    } 
} 
+0

'id' đã là loại con trỏ. 99,9% thời gian, bạn muốn sử dụng kiểu 'id' đơn giản, không phải là con trỏ tới một' id * '. –

Trả lời

10

Khi bạn làm

for (UITextField *text in... 

các con trỏ đối tượng từ mảng được đúc để UITextField * Loại - vì vậy nếu các đối tượng không phải là thực sự là một UITextField, tất cả các loại vật kỳ lạ có thể xảy ra nếu bạn cố gắng gọi Các phương thức UITextField.

Vì vậy, thay vì sử dụng các loại id (không * cần thiết, btw):

for (id obj in array) 

Sau đó kiểm tra kiểu như bạn làm và gọi các phương pháp thích hợp. Hoặc, lọc mảng để có được chỉ đối tượng của một loại nhất định, sau đó đi dù chỉ kiểu đó:

for (UITextField* text in [array filteredArrayUsingPredicate:...]) 

Edit: đây là cách để xây dựng các vị từ bộ lọc lớp:

Is it possible to filter an NSArray by class?

+0

Đối tượng không được truyền sang loại mới - con trỏ là. Các loại con trỏ không quan trọng một whit khi nói đến gửi tin nhắn. Bạn có thể gửi '-appendString:' tới một đối tượng bằng cách sử dụng một con trỏ kiểu 'NSWindow *' nếu bạn muốn, và nó sẽ hoạt động tốt miễn là con trỏ thực sự trỏ đến một cá thể của NSMutableString. (Bạn có thể nhận được một cảnh báo trình biên dịch, nhưng nó sẽ làm việc.) Nếu con trỏ trỏ đến một cửa sổ, mặc dù, bạn sẽ tất nhiên nhận được một lỗi trong thời gian chạy trừ khi bạn thực hiện các bước để ngăn chặn điều đó. – Caleb

+0

Bạn hoàn toàn đúng, tôi đã sửa đổi câu trả lời của mình cho phù hợp. – SVD

+0

phần cần chỉnh sửa là "nếu đối tượng không thực sự là một UITextField, tất cả các loại điều kỳ lạ có thể xảy ra ...". Nếu đối tượng không thực sự là một UITextField, bạn sẽ nhận được một ngoại lệ chọn unimplemented. – Caleb

5

điểm khai báo lớp của đối tượng là gì nếu tất cả các đối tượng trong mảng được chỉ định được thông qua qua vòng lặp?

Tên lớp chỉ ở đó để cho trình biên dịch biết những gì nó sẽ tìm thấy. Điều này cho phép nó cố gắng tìm ra phương pháp nào nó sẽ mong đợi bạn gọi và cách bạn có thể đối xử với đối tượng. Đó là ý tưởng tương tự khi đi qua một số int đến một phương thức mất float. Phương thức này sẽ không bỏ qua int - đó là giả sử bạn đang truyền đúng loại. Bạn chỉ cần đưa ra này xây dựng một ít tín dụng hơn đó là do:

for (UITextField *text in array) 

Nó chỉ không có chức năng đó. Cách bạn xử lý nó ngay bây giờ là cách chính xác.

0

Bạn có chắc chắn bạn không gặp lỗi khi bạn chạy mã đó? Thông báo "không phản hồi với bộ chọn" là lỗi thời gian chạy, không phải là lỗi thời gian biên dịch.Trình biên dịch không có ý tưởng cho dù các đối tượng trong mảng thực hiện -setText:, nhưng bạn chắc chắn sẽ nhận được một lỗi khi bạn thực sự gửi tin nhắn đó đến một thể hiện của UISegmentedControl.

Một khả năng khác là bạn có một lớp được gọi là UISegmentedController có phương thức -setText:. Tên của lớp triển khai tiện ích giao diện người dùng thanh-biểu đồ nhiều phần là UISegmentedControl. Vì vậy, mã bạn đang hiển thị không phải là mã thực, được kiểm tra hoặc bạn có một lớp mà chúng tôi không biết.

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