self
có thể được sử dụng trong một phương pháp học như một ví dụ lớp đa hình.
do đó, phương pháp lớp new
thể được thực hiện như thế này:
+ (id)new
{
return [[self alloc] init];
}
và sẽ trả lại đúng loại cho các ví dụ lớp được nhắn tin cho:
cũ a:
NSArray * a = [NSArray new]; // << a is an NSArray
ex b:
NSMutableArray * a = [NSMutableArray new]; // << a is an NSMutableArray
xem ghi chú bên dưới. Vì vậy, những gì bạn đang thực sự phải đối mặt với là đảm bảo chỉ có các phương thức cá thể trong giao thức, và các phương thức tự (lớp) của nó ánh xạ để áp dụng các phương thức cá thể trong giao thức.
Theo như thiết kế ... tốt, chúng ta hãy nói rằng tôi sẽ không viết nó theo cách này. Một singleton sẽ rõ ràng hơn và chính xác hơn, nhưng tôi thậm chí không thích những người độc thân nên tôi sẽ không đi theo con đường đó.
Cảnh báo được sản xuất bởi vì Lớp dụ (những gì được truyền) không áp dụng @protocol
định bởi tham số delegate
. Ví dụ Class
không phải là một thể hiện của lớp. Tuyên bố giao thức thực sự áp dụng cho trường hợp của lớp học. Ví dụ: nếu bạn áp dụng NSLocking
, trình biên dịch có mong đợi bạn cũng triển khai các phương thức lớp cho mọi phương thức mẫu được khai báo trong giao thức không? Trả lời: Không bao giờ. Việc thực hiện bạn đang đối phó với IMO là một trong những trường hợp mà nó là một lạm dụng ngôn ngữ, nhưng nó sẽ xảy ra để làm việc.
Để làm rõ các thuật ngữ:
Các "Class
dụ" là self
trong một phương pháp học:
+ (void)foo { self; }
An "thể hiện của lớp" là self
trong một phương pháp dụ:
- (void)foo { self; }
Trong thực tế, -[NSObject conformsToProtocol:]
là +[NSObject conformsToProtocol:]
và +[NSObject class]
chỉ trả lại self
do đó không có lỗi khi thực thi.
Tôi vẫn chưa rõ, tại sao tôi nhận được cảnh báo, nếu mã đáp ứng tiêu chí bạn mô tả.
Các tiêu chí tôi đã mô tả áp dụng cho thực hiện, nhưng nó lệch khỏi ngữ nghĩa của ngôn ngữ - do đó, trình biên dịch là hoàn toàn chính xác về vấn đề này.
Đối với một giải pháp cho vấn đề này: Không có cách nào để nói với trình biên dịch "dụ lớp của tôi phù hợp với giao thức " vì tuyên bố thông qua áp dụng cho thể hiện của lớp.
Bạn có hai lựa chọn chính:
Các sạch, cách tiếp cận đúng: Sử dụng một thể hiện của lớp và thực hiện các giao thức theo quy định.
hoặc định kiểu cá thể lớp giao thức:
id = đại biểu (id) tự; fbSession = [Phiên FBSessionĐối với ứng dụng: SHKFacebookKey getSessionProxy: SHKFacebookSessionProxyURL delegate: delegate];
Nếu bạn chọn # 2, nó có thể giúp xác định các phương pháp thể hiện của giao thức sử dụng phương pháp lớp học, như vậy:
+ (void)protocolMethod { /* do stuff */ }
- (void)protocolMethod { [self.class protocolMethod]; }
đó cũng sẽ bao hàm bạn không bao giờ cần phải trường hợp. Nó sẽ giúp bởi vì nó sẽ thêm cảnh báo nếu giao thức sẽ thay đổi. Những cảnh báo này sẽ bong bóng lên đến các phương thức lớp khi bạn theo quy ước.
Để giảm tiếng ồn, bạn cũng có thể xem xét việc tạo một số phương pháp để giảm định kiểu cho một vị trí:
+ (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return (id<SomeProtocol>)self;
}
- (id<SomeProtocol>)sharedSomeProtocolDelegate
{
return [[self class] sharedSomeProtocolDelegate];
}
sau đó bạn chỉ có thể viết:
fbSession = [FBSession sessionForApplication:SHKFacebookKey
getSessionProxy:SHKFacebookSessionProxyURL
delegate:[self sharedSomeProtocolDelegate]];
(lưu ý rằng việc triển khai của các loại này thực sự là các nhóm lớp và bạn sẽ thấy một thứ gì đó khác trong trình gỡ lỗi hoặc nếu được in)
Chỉnh sửa của bạn làm rõ. Giao thức chỉ chứa các phương thức ví dụ và không có phương thức nào trong số chúng đề cập đến người nhận, bằng cách này. Tôi vẫn chưa rõ, tại sao tôi nhận được cảnh báo, nếu mã đáp ứng các tiêu chí bạn mô tả. – Jim
@Jim detail added – justin