2011-01-10 12 views
12

Trong Objective-C khi bạn khai báo một biến Ví dụ bạn có thể kiểm tra nếu nó phù hợp với Nghị định thư về phân công tại thời gian biên dịch như sau:Kiểm tra xem một đối tượng phù hợp với hai giao thức riêng biệt trong Objective-C

id <MyProtocol> variable; 

Có thể kiểm tra xem một đối tượng được gán cho biến có phù hợp với hai giao thức riêng biệt tại thời gian biên dịch không? Như trong:

id <MyProtocol, MyOtherProtocol> variable; 

Tôi biết tôi có thể làm thời gian chạy kiểm tra sử dụng conformsToProtocol:respondsToSelector et al, (mà tôi làm trước khi thực sự sử dụng các đối tượng cho sự an toàn gia tăng), và tôi có thể viết phương pháp setter của riêng tôi mà không được kiểm tra , nhưng tôi muốn biết lúc biên dịch.

+0

Liệu không 'id biến;' công việc? Ít nhất nó biên dịch không có vấn đề gì ... – Vladimir

+0

Tôi hiện không ở máy tính mà tôi có thể kiểm tra, nhưng tôi muốn biết một cuộc thảo luận mà tôi đang có với một đồng nghiệp. – Jasarien

Trả lời

12

tôi hãy nghĩ tốt nhất là sử dụng mã của riêng bạn:

id <MyProtocol, MyOtherProtocol> variable; 

Và trước khi gọi phương thức, hãy kiểm tra xem biến có phản hồi những gì bạn muốn gọi không :

if ([variable respondsToSelector:@selector(aMethod:)]) { 
    [variable aMethod:nil]; 
} 

Vì mục tiêu-C là ngôn ngữ động, chỉ cần khai báo giao thức biến không thể đảm bảo rằng giao thức này tuân thủ giao thức. Nó chủ yếu sẽ tạo ra cảnh báo khi bạn xây dựng.

+0

Cảm ơn, tôi chỉ cần biết rằng cú pháp là hợp lệ và đã hoạt động. – Jasarien

3

Bạn không thể luôn luôn kiểm tra sự phù hợp của giao thức trong thời gian biên dịch vì đối tượng của loại (không đủ điều kiện) id luôn là đối tượng hợp lệ từ phối cảnh của trình biên dịch. Ví dụ,

id<P1> p1; 
id<P2> p2; 
id p0; 

// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>' 
p1 = p2; 

// no compiler warning 
p0 = p2; 
p1 = p0; 

Điều đó đang được nói, <P1, P2> sẽ cung cấp cho bạn những cảnh báo trong trường hợp đối tượng không phù hợp với cả hai giao thức nếu có thể được biết đến tại thời gian biên dịch:

id<P1> p1; 
id<P2> p2; 
id<P1, P2> p12; 
id<P1, P2> q12; 
id p0; 

p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>' 
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>' 
p12 = q12; // no compiler warning 

// no compiler warning 
p0 = p1; 
p12 = p0; 
47

Có, cú pháp đó là chính xác.

Cách đúng để kiểm tra xem một đối tượng phù hợp với một giao thức là để làm điều này:

if ([myObj conformsToProtocol:@protocol(MyProtocol)]) { 
    //conformance! 
} 

Lưu ý rằng điều này hoạt động như cả một phương pháp dụ và một phương pháp học.

Nếu vì một số lý do kỳ lạ bạn không thể sử dụng conformsToProtocol:, bạn có thể thả xuống mức runtime:

#import <objc/runtime.h> 

Protocol * p = objc_getProtocol("MyProtocol"); 
if (class_conformsToProtocol([myObj class], p)) { 
    //conformance! 
}