Câu trả lời:
Bạn không thể khai báo một phương thức được bảo vệ hoặc riêng tư. Bản chất động của Objective-C làm cho nó không thể thực hiện các điều khiển truy cập cho các phương thức. (Bạn có thể làm điều đó bằng cách sửa đổi nhiều trình biên dịch hoặc thời gian chạy, với một hình phạt tốc độ nghiêm trọng, nhưng vì những lý do rõ ràng, điều này không được thực hiện.)
Lấy từ Nguồn .
Bạn có thể mô phỏng quyền truy cập được bảo vệ và riêng tư vào các phương thức bằng cách thực hiện như sau:
Các biện pháp bảo vệ này, như Sachin đã lưu ý, không được thực thi trong thời gian chạy (ví dụ như trong Java).
UIGestureRecognizerSubclass.h
Đây là những gì tôi đã làm để hiển thị các phương thức được bảo vệ đối với các lớp con của mình mà không yêu cầu chúng thực hiện chính các phương thức đó. Điều này có nghĩa là tôi không nhận được cảnh báo trình biên dịch trong lớp con của mình về việc triển khai chưa hoàn thành.
SuperClassProtectedMethods.h (tệp giao thức):
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m: (trình biên dịch bây giờ sẽ buộc bạn thêm các phương thức được bảo vệ)
#import "SuperClassProtectedMethods.h"
@implementation SuperClass
- (void) protectedMethod:(NSObject *)foo {}
@end
SubClass.m:
#import "SuperClassProtectedMethods.h"
// Subclass can now call the protected methods, but no external classes importing .h files will be able to see the protected methods.
performSelector
vào nó.
[(id)obj hiddenMethod]
. Nói chính xác, phương pháp bảo vệ không được hỗ trợ trong Objective-C.
Tôi vừa phát hiện ra điều này và nó phù hợp với tôi. Để cải thiện câu trả lời của Adam, trong lớp cha của bạn, hãy thực hiện phương thức được bảo vệ trong tệp .m nhưng không khai báo nó trong tệp .h. Trong lớp con của bạn, hãy tạo một danh mục mới trong tệp .m của bạn với phần khai báo phương thức được bảo vệ của lớp cha và bạn có thể sử dụng phương thức được bảo vệ của lớp cha trong lớp con của mình. Điều này cuối cùng sẽ không ngăn người gọi phương thức được cho là được bảo vệ nếu bị ép buộc trong thời gian chạy.
/////// SuperClass.h
@interface SuperClass
@end
/////// SuperClass.m
@implementation SuperClass
- (void) protectedMethod
{}
@end
/////// SubClass.h
@interface SubClass : SuperClass
@end
/////// SubClass.m
@interface SubClass (Protected)
- (void) protectedMethod ;
@end
@implementation SubClass
- (void) callerOfProtectedMethod
{
[self protectedMethod] ; // this will not generate warning
}
@end
protectedMethod
Một cách khác bằng cách sử dụng các biến @protected.
@interface SuperClass:NSObject{
@protected
SEL protectedMehodSelector;
}
- (void) hackIt;
@end
@implementation SuperClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(baseHandling);
}
return self;
}
- (void) baseHandling {
// execute your code here
}
-(void) hackIt {
[self performSelector: protectedMethodSelector];
}
@end
@interface SubClass:SuperClass
@end
@implementation SubClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(customHandling);
}
return self;
}
- (void) customHandling {
// execute your custom code here
}
@end
Bạn có thể định nghĩa phương thức như một phương thức riêng của lớp cha và có thể sử dụng [super performSelector:@selector(privateMethod)];
trong lớp con.
Bạn có thể sắp xếp làm điều này với một danh mục.
@interface SomeClass (Protected)
-(void)doMadProtectedThings;
@end
@implementation SomeClass (Protected)
- (void)doMadProtectedThings{
NSLog(@"As long as the .h isn't imported into a class of completely different family, these methods will never be seen. You have to import this header into the subclasses of the super instance though.");
}
@end
Các phương thức sẽ không bị ẩn nếu bạn nhập danh mục trong một lớp khác, nhưng bạn không làm như vậy. Do tính chất động của Objective-C, thực sự không thể ẩn hoàn toàn một phương thức bất kể kiểu thể hiện đang gọi.
Cách tốt nhất để thực hiện có lẽ là danh mục tiếp tục lớp như được trả lời bởi @Brian Westphal nhưng bạn sẽ phải xác định lại phương thức trong danh mục này cho từng cá thể lớp con.
Một tùy chọn là sử dụng phần mở rộng lớp để ẩn các phương thức.
Trong .h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
Trong .m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
khai báo trong tệp .m. Bạn chỉ có thể khai báo một hàm và sử dụng nó và nó sẽ được coi là riêng tư.