답변:
protected 또는 private 메서드를 선언 할 수 없습니다 . Objective-C의 동적 특성은 메서드에 대한 액세스 제어를 구현하는 것을 불가능하게합니다. (컴파일러 나 런타임을 대폭 수정하여 상당한 속도 저하로이를 수행 할 수 있지만 명백한 이유로이 작업은 수행되지 않습니다.)
다음을 수행하여 메서드에 대한 보호 및 개인 액세스를 시뮬레이션 할 수 있습니다 .
이러한 보호 기능은 Sachin이 언급했듯이 런타임시 적용되지 않습니다 (예 : Java에서와 같이).
다음은 메서드 자체를 구현하지 않고도 하위 클래스에 보호 된 메서드를 표시하기 위해 수행 한 작업입니다. 이것은 불완전한 구현에 대한 내 하위 클래스에서 컴파일러 경고를받지 않았 음을 의미합니다.
SuperClassProtectedMethods.h (프로토콜 파일) :
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m : (컴파일러는 이제 보호 된 메서드를 추가하도록 강제합니다)
#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그것을 할 수 있습니다 .
[(id)obj hiddenMethod]. 정확히 말하면 보호 된 방법은 Objective-C에서 지원되지 않습니다.
나는 방금 이것을 발견했고 그것은 나를 위해 작동합니다. Adam의 대답을 개선하려면 수퍼 클래스에서 .m 파일에서 보호 된 메서드를 구현하지만 .h 파일에서 선언하지 마십시오. 서브 클래스에서 슈퍼 클래스의 보호 된 메서드 선언으로 .m 파일에 새 범주를 만들고 서브 클래스에서 슈퍼 클래스의 보호 된 메서드를 사용할 수 있습니다. 이것은 궁극적으로 런타임에 강제로 보호되는 메서드의 호출자를 막지는 못합니다.
/////// 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
@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
당신은 할 수 종류의 범주로이 작업을 수행.
@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
다른 클래스에서 범주를 가져 오면 메서드가 숨겨지지는 않지만 숨겨지지는 않습니다. Objective-C의 동적 특성으로 인해 호출하는 인스턴스 유형에 관계없이 메서드를 완전히 숨기는 것은 실제로 불가능합니다.
가장 좋은 방법은 아마도 @Brian Westphal이 대답 한 클래스 연속 범주 일 것입니다. 그러나 각 하위 클래스 인스턴스에 대해이 범주의 메서드를 다시 정의해야합니다.
한 가지 옵션은 클래스 확장 을 사용 하여 메서드를 숨기는 것입니다.
에서 .h:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
에서 .m:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface.m 파일에 선언이 필요하지 않다고 생각 합니다. 함수를 선언하고 사용할 수 있으며 개인용으로 취급됩니다.