जवाबों:
आप न तो संरक्षित या निजी विधि की घोषणा कर सकते हैं । उद्देश्य-सी की गतिशील प्रकृति तरीकों के लिए एक्सेस कंट्रोल को लागू करना असंभव बनाती है। (आप संकलक या रनटाइम को भारी गति से संशोधित करके, गंभीर गति से दंडित कर सकते हैं, लेकिन स्पष्ट कारणों से ऐसा नहीं किया गया है।)
सोर्स से लिया गया ।
आप निम्न करके विधियों में संरक्षित और निजी पहुँच का अनुकरण कर सकते हैं :
ये सुरक्षा नहीं हैं, जैसा कि सचिन ने उल्लेख किया है, रनटाइम पर लागू किया गया है (जैसा कि वे जावा में हैं, उदाहरण के लिए)।
UIGestureRecognizerSubclass.h
यहाँ है कि मैंने अपने उपवर्गों को दिखाई देने वाले संरक्षित तरीकों को प्राप्त करने के लिए क्या किया, बिना उन्हें खुद को लागू करने के तरीकों की आवश्यकता के। इसका मतलब था कि मुझे अधूरा कार्यान्वयन होने के बारे में मेरे उपवर्ग में संकलक चेतावनी नहीं मिली।
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]। सटीक रूप से कहा गया है, ऑब्जेक्टिव-सी में संरक्षित पद्धति का समर्थन नहीं किया गया है।
मैंने अभी इसे खोजा है और यह मेरे लिए काम करता है। एडम के जवाब में सुधार करने के लिए, अपने सुपरक्लास में .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
आप पैरेंट क्लास के एक निजी तरीके के रूप में विधि को परिभाषित कर सकते हैं और [super performSelector:@selector(privateMethod)];चाइल्ड क्लास में उपयोग कर सकते हैं ।
आप कर सकते हैं एक तरह से एक वर्ग के साथ ऐसा कर।
@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
यदि आप श्रेणी को किसी अन्य वर्ग में आयात करते हैं तो विधियाँ छिपी नहीं हैं, लेकिन आप अभी नहीं हैं। ऑब्जेक्टिव-सी की गतिशील प्रकृति के कारण एक कॉलिंग प्रकार की परवाह किए बिना एक विधि को पूरी तरह से छिपाना वास्तव में असंभव है।
जाने का सबसे अच्छा तरीका शायद वर्ग निरंतरता श्रेणी है जैसा कि @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 फ़ाइल में घोषणा की भी आवश्यकता है । आप केवल एक फ़ंक्शन की घोषणा कर सकते हैं और इसका उपयोग कर सकते हैं और यह इलाज निजी है।