2011-02-06 16 views
6

Ví dụ nếu có một 'xử lý tất cả' phương pháp loại ...iPhone, đang sử dụng isKindOfClass được coi là thực hành không tốt theo bất kỳ cách nào?

if ([obj isKindOfClass:class1]) { 
    // ... 
} else if ([obj isKindOfClass:class2]) { 
    // etc.. 

là xấu thực hành này? Có một lựa chọn thay thế hay một cách tốt hơn để cấu trúc mã?

Có nhược điểm nào trong thời gian chạy, dễ đọc, khả năng bảo trì hay bất kỳ thứ gì không?

Trả lời

7

Bất cứ khi nào một cái gì đó là được coi là thực tiễn tốt/xấu, ít nhiều chủ quan. Khi làm điều gì đó vốn đã là đúng/sai, nó ít nhiều là khách quan.

isKindOfClass: là một phương pháp hữu ích để kiểm tra thừa kế lớp. Nó trả lời câu hỏi duy nhất, "là đối tượng của một lớp mà là (một phân lớp của) một lớp nhất định?". Nó không trả lời bất kỳ câu hỏi nào khác như "đối tượng này có thực hiện phương thức đó theo cách riêng của nó không?" hoặc "Tôi có thể sử dụng đối tượng cho X hoặc Y không?". Nếu bạn sử dụng isKindOfClass: như dự định, bạn sẽ không gặp bất kỳ sự cố nào. Sau khi tất cả, trong một ngôn ngữ gõ động bạn nên có các công cụ để trích xuất thông tin meta về các đối tượng. isKindOfClass: chỉ là một trong những công cụ có sẵn.

Thực tế là một số đối tượng nhất định có thể nói dối về lớp học của họ không nên thực sự khiến bạn thất vọng. Họ chỉ ngụy trang mình là đối tượng của một lớp khác mà không phá vỡ bất cứ điều gì. Và nếu điều đó không phá vỡ bất cứ điều gì, tại sao tôi nên quan tâm?

Điều chính là bạn nên luôn nhớ sử dụng công cụ phù hợp cho bất kỳ mục đích cụ thể nào. Ví dụ: isKindOfClass: không thay thế cho respondsToSelector: hoặc conformsToProtocol:.

1

Sắp xếp. Câu hỏi này về cơ bản bao gồm những gì bạn đang yêu cầu: Is it safe to use isKindOfClass: against an NSString instance to determine type?

Có một số điều bạn cần ghi nhớ (xem liên kết ở trên), nhưng cá nhân tôi nghĩ đó là một phương pháp khá dễ đọc. Bạn chỉ cần đảm bảo rằng những gì bạn đang làm bên trong bài kiểm tra có điều kiện của bạn là thích hợp (ví dụ Apple đưa ra dọc theo dòng "một đối tượng có thể nói đó là một loại NSMutableArray, nhưng bạn có thể không thể thay đổi nó").

0

Tôi sẽ xem xét ví dụ bạn đã đưa ra để chống mẫu, vì vậy có, tôi sẽ nói là có hại. Sử dụng isKindOf như vậy là đánh bại đa hình và định hướng đối tượng.

tôi sẽ xa thích mà bạn gọi:

[obj doTheThing]; 

và sau đó thực hiện doTheThing khác nhau trong các lớp con của bạn.

Nếu obj có thể thuộc về các lớp mà bạn không có quyền kiểm soát, hãy sử dụng các danh mục để thêm phương thức doTheThing của bạn vào chúng. Nếu bạn cần hành vi mặc định, hãy thêm một danh mục trên NSObject.

Đây là giải pháp sạch hơn theo ý kiến ​​của tôi và giúp phân tách logic (những gì bạn đang làm) từ chi tiết triển khai (cách thực hiện nó cho các loại đối tượng cụ thể khác nhau).

+0

Thực hiện các phương pháp trong các danh mục chỉ để tránh nhu cầu sử dụng các công cụ nội quan âm thanh tệ hơn với tôi. iE NSJSONSerialization 'JSONObjectWithData: options: error:' có thể trả về các kiểu khác nhau. (Mảng, từ điển).hacking phương pháp từ điển vào mảng và ngược lại âm thanh cực kỳ ngu ngốc với tôi. – vikingosegundo

+0

Điều gì xảy ra nếu chỉ một lớp con cần có phương pháp? –

+0

Nếu chỉ có một lớp con cần phải có một phương thức, sau đó có một phương thức trong lớp cơ sở với một thực hiện mặc định mà không làm gì cả, và một phương thức ghi đè trong lớp con thực hiện điều gì đó. –

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