উদ্দেশ্য-সি তে সুরক্ষিত পদ্ধতিগুলি


112

উদ্দেশ্য-সি এর সুরক্ষিত পদ্ধতির সমতুল্য কী? আমি এমন পদ্ধতিগুলি সংজ্ঞায়িত করতে চাই যা কেবল উত্পন্ন ক্লাসগুলি কল / প্রয়োগ করতে পারে।

উত্তর:


47

আপনি কোনও পদ্ধতিই সুরক্ষিত বা ব্যক্তিগত হিসাবে ঘোষণা করতে পারবেন না । উদ্দেশ্য-সি এর গতিশীল প্রকৃতি পদ্ধতির জন্য অ্যাক্সেস নিয়ন্ত্রণগুলি প্রয়োগ করা অসম্ভব করে তোলে। (আপনি কঠোর গতির জরিমানার সময় ভারসাম্যভাবে সংকলক বা রানটাইম সংশোধন করে এটি করতে পারেন, তবে স্পষ্ট কারণেই এটি করা হয়নি))

উত্স থেকে নেওয়া ।


প্রযুক্তিগতভাবে আপনি যখন পারবেন না, আপনি ব্যক্তিগত ভেরিয়েবলগুলি অনুকরণ করতে পারেন।
শরেন ইয়ার্স

লি - আপনি যদি @ সুরক্ষিত কোনও ফাংশন পয়েন্টার ঘোষণা করেন এবং আর ডি পদ্ধতিতে কোনও ফাংশন বরাদ্দ করেন তবে এটি কি কাজ করবে?
বিক্রম990

156

আপনি নিম্নলিখিতগুলি দ্বারা পদ্ধতিগুলিতে সুরক্ষিত এবং ব্যক্তিগত অ্যাক্সেস অনুকরণ করতে পারেন :

  • ক্লাস এক্সটেনশনে আপনার ব্যক্তিগত পদ্ধতিগুলি ঘোষণা করুন (অর্থাত 'বর্গ' .m ফাইলের শীর্ষের কাছে ঘোষিত একটি নামবিহীন বিভাগ)
  • সাবক্লাস শিরোনামে আপনার সুরক্ষিত পদ্ধতিগুলি ঘোষণা করুন - অ্যাপল এই প্যাটার্নটি ইউআইজিস্টচাররনগনাইজারের সাথে ব্যবহার করে (ইউআইজিস্টচারআরকনাইজারসুব্লাস.এল এর জন্য ডকুমেন্টেশন এবং রেফারেন্স দেখুন)

এই সুরক্ষাগুলি যেমন রচনার সময় প্রয়োগ করা হয়নি (যেমন তারা জাভাতে রয়েছে, উদাহরণস্বরূপ) noted


2
ইউআইজিএসচারআর সনাক্তকারী-জাতীয় সমাধান সম্পর্কে: সমস্যাটি হ'ল কিছু কোড সাবক্লাস আমদানি করলে এটি সাবক্লাস শিরোনামটিও আমদানি করে এবং তাই এটি "সুরক্ষিত" পদ্ধতিতে অ্যাক্সেস পেতে পারে। যে কাছাকাছি একটি উপায় আছে কি?
ইয়োনিক্স

5
হাই ইয়োনিক্স, সাবক্লাস শিরোনামের জন্য আমদানি .h ফাইলের অভ্যন্তরে নয়। এম ফাইলের ভিতরে করা হবে, সুতরাং সাবক্লাসটি আমদানি করা এই সুরক্ষিত পদ্ধতিগুলি আমদানি করতে পারে না।
ব্রায়ান ওয়েস্টফাল

দুর্দান্ত পরামর্শ ব্রায়ান, ধন্যবাদ একটি টন !! মূল পোস্টার হিসাবে, ঘোষিত বৈশিষ্ট্যের জন্য, কেবল নিশ্চিত করুন যে আপনি সাবক্লাসের শ্রেণিবদ্ধকরণ (নামবিহীন বিভাগ) বাস্তবায়নে @dynamic ব্যবহার করেছেন, যাতে রানটাইম সময়ে, প্যারেন্ট ক্লাসের প্রয়োগটি ব্যবহৃত হবে
user1046037

1
আমি কীভাবে ইউআইজিস্টারআরকিগনাইজারসুব্লাস।?
শরেন ইয়ার্স

5
অভ্যন্তরীণভাবে অ্যাপল এটি করে কীভাবে তা নির্দেশ করার জন্য ধন্যবাদ। অ্যাপল যেভাবে স্টাফ প্রয়োগ করে সেভাবে কীভাবে জিনিসগুলি প্রয়োগ করতে হয় তার একটি সম্পূর্ণ উদাহরণ আমি পোস্ট করেছিUIGestureRecognizerSubclass.h
ডার্টি হেনরি

14

সুরক্ষিত পদ্ধতিগুলি আমার উপশ্রেণীর কাছে দৃশ্যমান হয়ে ওঠার জন্য আমি এখানে কী করেছি, সেগুলি নিজেরাই পদ্ধতিগুলি প্রয়োগ করার প্রয়োজন ছাড়াই। এর অর্থ আমি আমার সাবক্লাসে অসম্পূর্ণ বাস্তবায়ন সম্পর্কে সংকলক সতর্কতা পাইনি।

সুপারক্লাসপ্রোটেক্টেড ম্যাথোডস.হ। (প্রোটোকল ফাইল):

@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end

@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end

সুপারক্লাস.এম: (সংকলক এখন আপনাকে সুরক্ষিত পদ্ধতিগুলি যুক্ত করতে বাধ্য করবে)

#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.

2
সুরক্ষিত অর্থ এটি বাহ্যিকভাবে বলা যায় না । আপনি এখনও ক্লাসে নির্ধারিত কোনও পদ্ধতিতে বাহ্যিকভাবে দৃশ্যমান বা না থাকুক কল করতে পারেন call
eonil

হ্যাঁ, আমি এটি বুঝতে পারি। এই পদ্ধতিটি মানুষের মস্তিষ্কের জন্য কাজ করে, প্রকৃত সংকলিত কোড নয়। তবে অবজেক্টিভ-সি সেটি অনুমতি দেয় না (বাহ্যিকভাবে কল করতে সক্ষম হচ্ছে না)। আপনি সর্বদা performSelectorএটি করতে পারেন ।
মাইকেল কের্নাহান

1
এছাড়াও আপনি কি করতে পারেন [(id)obj hiddenMethod]। সঠিকভাবে বলছি, সুরক্ষিত পদ্ধতিটি উদ্দেশ্য-সি তে সমর্থিত নয়।
eonil

এটির সাথে সমস্যা হ'ল আপনার তথাকথিত সুরক্ষিত শ্রেণিগুলি সম্পত্তি বৈশিষ্ট্যগুলি বিজ্ঞাপন করতে পারে না। আপনার যদি সম্পত্তিগুলির প্রয়োজন না হয় তবে যে কেউ ঠিকভাবে জানেন যে আপনি কেবল সুরক্ষিত বিভাগগুলি যুক্ত করতে পারেন।
শরেন ইয়ার্স

@ ইউনিল: "আপনি [(আইডি) আপত্তি লুকানো ম্যাথোড] করতেও পারেন" " হ্যাঁ, আপনি এটি করতে পারেন তবে সেই পদ্ধতিটি কোনও অন্তর্ভুক্ত ইন্টারফেসে না থাকলে আপনি সংকলকটির কাছ থেকে একটি সতর্কতা পাবেন।
কাইসরুদ্দি

9

আমি কেবল এটি আবিষ্কার করেছি এবং এটি আমার পক্ষে কাজ করে 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

2
এই ক্ষেত্রে protectedMethod
সংকলকটি

এটি প্রায়শই ভাল কাজ তবে বিভাগ (সুরক্ষিত) না করে আপনি একটি এক্সটেনশান করতে পারেন।
ধর্মেশ সিদ্ধপুরা

@ স্কাইওয়িন্দার সম্ভবত এটি পূর্ববর্তী সংস্করণে হয়েছিল তবে এক্সকোডের বর্তমান সংস্করণগুলিতে এই সমাধানটি নিয়ে কোনও সমস্যা নেই।
ড্যারেন এহলার্স 21

2

@ সুরক্ষিত ভেরিয়েবলগুলি ব্যবহার করার আর একটি উপায়।

@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

এবং আপনি সুরক্ষিত আইভারসকে ক্লাস এক্সটেনশনে একটি সুরক্ষিত নামের হেডার ফাইলটিতেও
রাখতে পারেন

1

আপনি পিতামাত্ত শ্রেণীর একটি ব্যক্তিগত পদ্ধতি হিসাবে পদ্ধতিটি সংজ্ঞায়িত করতে পারেন [super performSelector:@selector(privateMethod)];এবং শিশু শ্রেণিতে ব্যবহার করতে পারেন ।


0

আপনি এই বিভাগে বাছাই করতে পারেন

@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

আপনি যদি অন্য শ্রেণিতে বিভাগটি আমদানি করেন তবে পদ্ধতিগুলি গোপন করা হয় না, তবে আপনি কেবল এটি করেন না। অবজেক্টিভ-সি এর গতিশীল প্রকৃতির কারণে কলিং ইনস্ট্যান্সের ধরণ নির্বিশেষে কোনও পদ্ধতি সম্পূর্ণভাবে আড়াল করা অসম্ভব।

যাওয়ার সর্বোত্তম উপায়টি সম্ভবত ব্রেইন ওয়েস্টফালের উত্তর অনুসারে ক্লাসের ধারাবাহিকতা বিভাগ তবে আপনার প্রতিটি উপবিষ্ট উদাহরণের জন্য আপনাকে এই বিভাগে পদ্ধতিটি নতুনভাবে সংজ্ঞায়িত করতে হবে।


0

একটি বিকল্প ব্যবহার করা বর্গ এক্সটেনশন আড়াল পদ্ধতি।

ইন .h:

@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

ইন .m:

@interface SomeAppDelegate()
- (void)localMethod;
@end

@implementation SomeAppDelegate

- (void)localMethod
{
}

@end

আমিও মনে করি @interfaceনা। M ফাইলটিতে আপনার ঘোষণার দরকার আছে । আপনি কেবল একটি ফাংশন ঘোষণা করতে এবং এটি ব্যবহার করতে পারেন এবং এটি ব্যক্তিগত হিসাবে বিবেচিত হবে।
রাশ

1
লক্ষ্য করুন যে কেবলমাত্র উদ্দেশ্য সি-তে সাম্প্রতিক আপডেটের সাথে এটি সত্য that
গিলিয়াম লরেন্ট

0

আমি সাধারণত অভ্যন্তরীণ উপসর্গ সহ সুরক্ষিত পদ্ধতির নাম রাখি:

-(void) internalMethod;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.