উদ্দেশ্য সি-তে সুইজলিংয়ের পদ্ধতিগুলি কী কী?


235

আমি লোকদের শুনেছি যে পদ্ধতিতে সুইজল করা একটি বিপজ্জনক অনুশীলন। এমনকি নাম সুইজলিং পরামর্শ দেয় যে এটি কিছুটা ঠকানো।

পদ্ধতি সুইজলিং ম্যাপিংটি সংশোধন করছে যাতে কলিং সিলেক্টর এ প্রকৃতপক্ষে বাস্তবায়নের জন্য প্রার্থনা করবে বি এর উত্স শ্রেণীর আচরণ বৃদ্ধি করা this

আমরা কি ঝুঁকিগুলি আনুষ্ঠানিক করতে পারি যাতে যে কেউ সুইজলিং ব্যবহার করবেন কিনা তা সিদ্ধান্ত নিচ্ছেন তারা কি করার চেষ্টা করছেন তার জন্য এটি উপযুক্ত কিনা তা একটি বুদ্ধিমান সিদ্ধান্ত নিতে পারে।

যেমন

  • নামকরণের সংঘর্ষ : যদি ক্লাসটি পরে যুক্ত করেছে তার নামটি অন্তর্ভুক্ত করার জন্য যদি এর কার্যকারিতা বাড়িয়ে তোলে তবে এটি একটি বিশাল ধরণের সমস্যার কারণ হতে পারে। বুদ্ধিমানভাবে সুইজলড পদ্ধতিতে নামকরণ করে ঝুঁকি হ্রাস করুন।

আপনি যে কোডটি পড়েছেন তার কাছ থেকে আপনি প্রত্যাশিত অন্য কিছু পাওয়ার জন্য ইতিমধ্যে খুব ভাল নয়
মার্টিন বাবাকায়েভ

পাইথন সাজসজ্জাকারীরা খুব পরিষ্কার
ক্লোডিউ

উত্তর:


439

আমি মনে করি এটি সত্যিই দুর্দান্ত প্রশ্ন, এবং এটি লজ্জার বিষয় যে আসল প্রশ্নটি মোকাবেলা করার পরিবর্তে বেশিরভাগ উত্তরই বিষয়টি এড়িয়ে গেছে এবং কেবল সুইজলিং ব্যবহার না করার জন্য বলেছে।

পদ্ধতি সিজলিংয়ের ব্যবহার রান্নাঘরের ধারালো ছুরি ব্যবহার করার মতো। কিছু লোক ধারালো ছুরির কারণে ভীত হয় কারণ তারা মনে করে যে তারা নিজেরাই খারাপভাবে কাটবে, তবে সত্যটি হ'ল ধারালো ছুরিগুলি আরও নিরাপদ

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

পটভূমি

সমস্ত নকশার নিদর্শনগুলির মতো, যদি আমরা প্যাটার্নটির পরিণতি সম্পর্কে পুরোপুরি সচেতন হই, তবে এটি ব্যবহার করবেন কি না সে সম্পর্কে আমরা আরও জ্ঞাত সিদ্ধান্ত নিতে সক্ষম হয়েছি। সিঙ্গলেটগুলি এমন কোনও জিনিসের একটি ভাল উদাহরণ যা বেশ বিতর্কিত, এবং সঙ্গত কারণে - সঠিকভাবে প্রয়োগ করা সত্যই তাদের পক্ষে শক্ত। যদিও এখনও অনেকে সিলেটলেট ব্যবহার করতে পছন্দ করে। সুইজলিংয়ের ক্ষেত্রেও একই কথা বলা যেতে পারে। ভাল এবং খারাপ উভয়ই পুরোপুরি বুঝতে পারলে আপনার নিজের মতামত তৈরি করা উচিত।

আলোচনা

পদ্ধতির সুইজলিংয়ের কয়েকটি সমস্যা এখানে রয়েছে:

  • পদ্ধতি সুইজলিং পারমাণবিক নয়
  • মালিকানাবিহীন কোডের আচরণের পরিবর্তন করে
  • সম্ভাব্য নাম দ্বন্দ্ব
  • সুইজলিং পদ্ধতিটির যুক্তিগুলিকে পরিবর্তন করে
  • সুইজার্সের ক্রমটি গুরুত্বপূর্ণ
  • বুঝতে অসুবিধা (পুনরাবৃত্ত লাগছে)
  • ডিবাগ করা কঠিন

এই পয়েন্টগুলি সমস্ত বৈধ, এবং এগুলিকে সম্বোধন করার ক্ষেত্রে আমরা পদ্ধতি সাঁতার কাটা সম্পর্কে আমাদের বোঝার পাশাপাশি ফলাফল অর্জনের জন্য ব্যবহৃত পদ্ধতিগুলি উভয়কে উন্নত করতে পারি। আমি প্রত্যেককে একবারে নিয়ে যাব।

পদ্ধতি সুইজলিং পারমাণবিক নয়

আমি এখনও পদ্ধতি সুইজলিংয়ের একটি বাস্তবায়ন দেখতে পাই যা একই সাথে 1 ব্যবহার করা নিরাপদ । আপনি পদ্ধতি সুইজলিং ব্যবহার করতে চান এমন 95% ক্ষেত্রে এটি আসলে কোনও সমস্যা নয়। সাধারণত, আপনি কেবল কোনও পদ্ধতির বাস্তবায়ন প্রতিস্থাপন করতে চান এবং আপনি চান যে প্রয়োগটি আপনার প্রোগ্রামের পুরো জীবনকালের জন্য ব্যবহার করা হোক। এর অর্থ হ'ল আপনার পদ্ধতিটি সাঁতার কাটা উচিত +(void)loadloadবর্গ পদ্ধতি আপনার আবেদন শুরুতে ধারাবাহিকভাবে মৃত্যুদন্ড কার্যকর করা হয়। আপনি যদি এখানে আপনার সুইজলিং করেন তবে সম্মতিতে কোনও সমস্যা নেই। আপনি যদি +(void)initializeঘুরে বেড়াতে থাকেন তবে আপনি নিজের সুইজলিং বাস্তবায়নে একটি রেসের শর্তটি শেষ করতে পারেন এবং রানটাইমটি একটি অদ্ভুত অবস্থায় শেষ করতে পারে।

মালিকানাবিহীন কোডের আচরণের পরিবর্তন করে

এটি সুইজলিংয়ের একটি সমস্যা, তবে এটি পুরোপুরি বিষয় kind লক্ষ্যটি হল যে কোডটি পরিবর্তন করতে সক্ষম হোন। লোকেদের এটি একটি বড় চুক্তি হিসাবে চিহ্নিত করার কারণ হ'ল আপনি NSButtonযে জিনিসগুলির জন্য পরিবর্তন করতে চান তার একটি উদাহরণের জন্য আপনি কেবল জিনিসগুলি পরিবর্তন করছেন না , পরিবর্তে NSButtonআপনার অ্যাপ্লিকেশনটির সমস্ত দৃষ্টান্তের জন্য । এই কারণে, যখন আপনি সাঁতার কাটাচ্ছেন তখন আপনার সতর্ক হওয়া উচিত তবে আপনার এটি পুরোপুরি এড়ানো উচিত নয়।

এটিকে এভাবে ভাবুন ... আপনি যদি কোনও ক্লাসে কোনও পদ্ধতিকে ওভাররাইড করে থাকেন এবং আপনি সুপার ক্লাস পদ্ধতিটি না কল করেন, আপনার সমস্যা দেখা দিতে পারে। বেশিরভাগ ক্ষেত্রে, সুপার ক্লাসটি সেই পদ্ধতিটি কল করার প্রত্যাশা করে (অন্যথায় ডকুমেন্টেড না হলে)। আপনি যদি এই একই চিন্তাকে সুইজলিংয়ে প্রয়োগ করেন তবে আপনি বেশিরভাগ বিষয় coveredেকে রেখেছেন। সবসময় আসল বাস্তবায়ন কল করুন। আপনি যদি তা না করেন তবে আপনি নিরাপদে থাকার জন্য সম্ভবত খুব বেশি পরিবর্তন করছেন।

সম্ভাব্য নাম দ্বন্দ্ব

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

@interface NSView : NSObject
- (void)setFrame:(NSRect)frame;
@end

@implementation NSView (MyViewAdditions)

- (void)my_setFrame:(NSRect)frame {
    // do custom work
    [self my_setFrame:frame];
}

+ (void)load {
    [self swizzle:@selector(setFrame:) with:@selector(my_setFrame:)];
}

@end

এটি ঠিক কাজ করে, তবে my_setFrame:অন্য কোথাও সংজ্ঞায়িত হলে কী হবে ? এই সমস্যাটি সাঁতার কাটার জন্য অনন্য নয়, তবে আমরা যেকোনভাবে এটি ঘিরে কাজ করতে পারি। কর্মক্ষেত্রের অন্যান্য সমস্যাগুলিও সমাধান করার একটি অতিরিক্ত সুবিধা রয়েছে। পরিবর্তে আমরা যা করি তা এখানে:

@implementation NSView (MyViewAdditions)

static void MySetFrame(id self, SEL _cmd, NSRect frame);
static void (*SetFrameIMP)(id self, SEL _cmd, NSRect frame);

static void MySetFrame(id self, SEL _cmd, NSRect frame) {
    // do custom work
    SetFrameIMP(self, _cmd, frame);
}

+ (void)load {
    [self swizzle:@selector(setFrame:) with:(IMP)MySetFrame store:(IMP *)&SetFrameIMP];
}

@end

যদিও এটি কিছুটা কম অবজেক্টিভ-সি-এর মতো দেখায় (যেহেতু এটি ফাংশন পয়েন্টার ব্যবহার করছে), এটি কোনও নামকরণ বিরোধকে এড়িয়ে চলে। নীতিগতভাবে, এটি স্ট্যান্ডার্ড সুইজলিংয়ের মতো ঠিক একই জিনিস করছে। এটি কিছুক্ষণের জন্য সংজ্ঞায়িত হওয়ার সাথে সাথে সুইজলিং ব্যবহার করছে এমন লোকদের জন্য এটি কিছুটা পরিবর্তন হতে পারে তবে শেষ পর্যন্ত, আমি মনে করি এটি আরও ভাল। সুইজলিং পদ্ধতিটি এভাবে সংজ্ঞায়িত করা হয়:

typedef IMP *IMPPointer;

BOOL class_swizzleMethodAndStore(Class class, SEL original, IMP replacement, IMPPointer store) {
    IMP imp = NULL;
    Method method = class_getInstanceMethod(class, original);
    if (method) {
        const char *type = method_getTypeEncoding(method);
        imp = class_replaceMethod(class, original, replacement, type);
        if (!imp) {
            imp = method_getImplementation(method);
        }
    }
    if (imp && store) { *store = imp; }
    return (imp != NULL);
}

@implementation NSObject (FRRuntimeAdditions)
+ (BOOL)swizzle:(SEL)original with:(IMP)replacement store:(IMPPointer)store {
    return class_swizzleMethodAndStore(self, original, replacement, store);
}
@end

নাম পরিবর্তন করে সাঁতার কাটা পদ্ধতিটির আর্গুমেন্টগুলিকে পরিবর্তন করে

এটি আমার মনের মধ্যে বড়। এই কারণে স্ট্যান্ডার্ড পদ্ধতি সুইজলিং করা উচিত নয়। আপনি মূল পদ্ধতির বাস্তবায়নে পাস হওয়া যুক্তিগুলি পরিবর্তন করছেন। এটি যেখানে এটি ঘটে:

[self my_setFrame:frame];

এই লাইনটি যা করে তা হ'ল:

objc_msgSend(self, @selector(my_setFrame:), frame);

যা বাস্তবায়নটি দেখার জন্য রানটাইম ব্যবহার করবে my_setFrame:। একবার প্রয়োগটি পাওয়া গেলে, এটি একই যুক্তি দিয়ে বাস্তবায়নের জন্য অনুরোধ জানায়। এটি যে বাস্তবায়নটি আবিষ্কার করে তা হ'ল আসল বাস্তবায়ন setFrame:, সুতরাং এটি এগিয়ে যায় এবং এটি কল করে, তবে _cmdযুক্তিটি setFrame:এটির মতো হওয়া উচিত নয় । এখন my_setFrame:। আসল বাস্তবায়নটি এমন যুক্তি দিয়ে ডাকা হচ্ছে যা এটি প্রত্যাশা করে না যে এটি পাবে। এটা ভাল না।

একটি সহজ সমাধান আছে - উপরে সংজ্ঞায়িত বিকল্প সুইজলিং কৌশল ব্যবহার করুন। যুক্তিগুলি অপরিবর্তিত থাকবে!

সুইজার্সের ক্রমটি গুরুত্বপূর্ণ

যে পদ্ধতিতে পদ্ধতিগুলি সুইজল বিষয়গুলিতে আসে। ধরে setFrame:নেওয়া কেবলমাত্র এটির উপর সংজ্ঞায়িত করা হয় NSView, জিনিসগুলির এই ক্রমটি কল্পনা করুন:

[NSButton swizzle:@selector(setFrame:) with:@selector(my_buttonSetFrame:)];
[NSControl swizzle:@selector(setFrame:) with:@selector(my_controlSetFrame:)];
[NSView swizzle:@selector(setFrame:) with:@selector(my_viewSetFrame:)];

পদ্ধতিটি NSButtonসুইজল হয়ে গেলে কী হবে ? ওয়েল সবচেয়ে swizzling নিশ্চিত করবে যে এটা বাস্তবায়ন প্রতিস্থাপন না setFrame:সকল দর্শনের জন্য, তাই এটি হবে টেনে উদাহরণস্বরূপ পদ্ধতি। -সংজ্ঞায়িত পুনরায় এই বিদ্যমান বাস্তবায়ন ব্যবহার করবে setFrame:মধ্যে NSButtonবর্গ যাতে বাস্তবায়নের বিনিময় সকল দৃশ্য প্রভাবিত করে না। বিদ্যমান বাস্তবায়ন যার উপর নির্ধারিত হয় NSView। সুইজল করার সময় একই জিনিস ঘটবে NSControl(আবার NSViewবাস্তবায়নটি ব্যবহার করে )।

আপনি যখন setFrame:একটি বোতামে কল করবেন তখন এটি আপনার সুইজল পদ্ধতিটিকে কল করবে এবং তারপরে setFrame:মূলত সংজ্ঞায়িত পদ্ধতিটিতে সরাসরি লাফিয়ে উঠবে NSViewNSControlএবং NSViewswizzled বাস্তবায়নের আহ্বান করা হবে না।

তবে যদি আদেশটি ছিল:

[NSView swizzle:@selector(setFrame:) with:@selector(my_viewSetFrame:)];
[NSControl swizzle:@selector(setFrame:) with:@selector(my_controlSetFrame:)];
[NSButton swizzle:@selector(setFrame:) with:@selector(my_buttonSetFrame:)];

যেহেতু ভিউ সুইজলিং আগে স্থান নেয়, তাই নিয়ন্ত্রণের সুইজলিং সঠিক পদ্ধতিটি টানতে সক্ষম হবে । অনুরূপভাবে, যেহেতু নিয়ন্ত্রণ swizzling বোতাম swizzling সামনে, বোতাম হবে টেনে নিয়ন্ত্রণ এর swizzled বাস্তবায়ন setFrame:। এটি কিছুটা বিভ্রান্তিকর, তবে এটি সঠিক ক্রম। আমরা কীভাবে এই ক্রমটি নিশ্চিত করতে পারি?

আবার, কেবল loadসুইজল জিনিসগুলি ব্যবহার করুন । আপনি যদি সুইজল করেন loadএবং আপনি কেবল ক্লাসে বোঝা হচ্ছে এমন পরিবর্তনগুলি করেন তবে আপনি নিরাপদে থাকবেন। loadপদ্ধতি গ্যারান্টী যে সুপার বর্গ লোড পদ্ধতি কোনো উপশ্রেণী সামনে ডাকা হবে। আমরা ঠিক সঠিক অর্ডার পাবেন!

বুঝতে অসুবিধা (পুনরাবৃত্ত লাগছে)

একটি traditionতিহ্যগতভাবে সংজ্ঞায়িত সুইজল পদ্ধতিটি দেখে আমি মনে করি কী চলছে তা বলা সত্যিই শক্ত। তবে উপরের সুইজলিংয়ের বিকল্প পদ্ধতিটি দেখে, এটি বোঝা বেশ সহজ। এটি ইতিমধ্যে সমাধান করা হয়েছে!

ডিবাগ করা কঠিন

ডিবাগিংয়ের সময় একটি বিভ্রান্তি একটি অদ্ভুত ব্যাকট্রেস দেখছে যেখানে গলিত নামগুলি মিশ্রিত হয়ে সমস্ত কিছু আপনার মাথার মধ্যে ঝাঁপিয়ে পড়ে। আবার, বিকল্প বাস্তবায়ন এটিকে সম্বোধন করে। আপনি ব্যাকট্রেসগুলিতে পরিষ্কারভাবে নামযুক্ত ফাংশন দেখতে পাবেন। তবুও, সুইজলিং ডিবাগ করা কঠিন হতে পারে কারণ সুইজলিংয়ের ফলে কী প্রভাব পড়ছে তা মনে রাখা শক্ত। আপনার কোডটি ভালভাবে নথিভুক্ত করুন (এমনকি যদি আপনি ভাবেন যে আপনিই কেবল এটি দেখেন তবেই)। ভাল অনুশীলনগুলি অনুসরণ করুন, এবং আপনি ঠিক থাকবেন। মাল্টি-থ্রেড কোডের চেয়ে ডিবাগ করা শক্ত নয়।

উপসংহার

সঠিকভাবে ব্যবহার করা হলে পদ্ধতি সুইজলিং নিরাপদ। একটি সরল নিরাপত্তা পরিমাপ আপনি গ্রহণ করতে পারেন শুধুমাত্র পাঁচমিশালী মদ্যবিশেষ হয় load। প্রোগ্রামিংয়ের অনেক কিছুর মতো, এটি বিপজ্জনক হতে পারে তবে এর পরিণতিগুলি বোঝা আপনাকে এটিকে সঠিকভাবে ব্যবহার করতে দেয়।


1 উপরের সংজ্ঞায়িত সুইজলিং পদ্ধতিটি ব্যবহার করে আপনি যদি ট্রাম্পলাইনগুলি ব্যবহার করেন তবে আপনি জিনিসগুলিকে থ্রেডটি নিরাপদ করে তুলতে পারেন। আপনার দুটি ট্রামপোলিন লাগবে। পদ্ধতির শুরুতে, আপনাকে ফাংশন পয়েন্টারটি নির্ধারণ করতে হবে store, কোনও ফাংশন যা স্প্রে হয়ে গেছে যতক্ষণ না ঠিকানাটি storeপরিবর্তিত হয়েছে until এটি কোনও ক্রিয়াকলাপের শর্ত এড়াতে পারে যেখানে storeফাংশন পয়েন্টার সেট করতে সক্ষম হওয়ার আগে সুইজল পদ্ধতিটি কল করা হয়েছিল । তারপরে আপনার ক্ষেত্রে ট্রামপোলিন ব্যবহার করা দরকার যেখানে প্রয়োগটি ইতিমধ্যে শ্রেণিতে সংজ্ঞায়িত করা হয়নি এবং ট্রামপোলিন লুক রয়েছে এবং সুপার ক্লাস পদ্ধতিটি সঠিকভাবে কল করতে হবে। পদ্ধতির সংজ্ঞা দেওয়া যাতে এটি কার্যকরভাবে সুপার বাস্তবায়িত হয় তা নিশ্চিত করবে যে সুইজলিং কলগুলির ক্রম কোনও ব্যাপার না।


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

আপনার অভিজ্ঞতার মধ্যে সুইজলিং অ্যাপ স্টোরগুলিতে গ্রহণযোগ্য কিনা তা আপনি উল্লেখ করতে পারেন। আমি আপনাকে স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 8834294 এও পরিচালনা করছি ।
ডিকি সিং

3
সুইজার্লিং অ্যাপ স্টোরটিতে ব্যবহার করা যেতে পারে। অনেক অ্যাপস এবং ফ্রেমওয়ার্কগুলি (আমাদের অন্তর্ভুক্ত) থাকে। উপরের সমস্ত কিছু এখনও অবধি রয়েছে এবং আপনি ব্যক্তিগত পদ্ধতিগুলি ঘুরে বেড়াতে পারবেন না (আসলে, আপনি প্রযুক্তিগতভাবে পারেন তবে আপনি প্রত্যাখ্যান এবং এর ঝুঁকিগুলি অন্য কোনও থ্রেডের জন্য)।
wbyoung

আশ্চর্যজনক উত্তর। তবে কেন + swizzle এর পরিবর্তে ক্লাস_সুইজল মেথডএন্ডস্টোর () এ সুইজিং তৈরি করুন: সহ: স্টোর :? কেন এই অতিরিক্ত ফাংশন?
ফ্রিজল্যাব

2
@ ফ্রিজল্যাব ভালো প্রশ্ন! এটি সত্যিই কেবল একটি স্টাইলের জিনিস। আপনি যদি এমন একগুচ্ছ কোড লিখছেন যা উদ্দেশ্যমূলক-সি রানটাইম এপিআই (সি তে) এর সাথে সরাসরি কাজ করছে, তবে ধারাবাহিকতার জন্য এটিকে সি স্টাইল বলতে সক্ষম হওয়াই ভাল। এর বাইরে আমি ভাবতে পারি তার একমাত্র কারণ আপনি যদি খাঁটি সি তে কিছু লিখে থাকেন তবে এটি আরও কলযোগ্য। যদিও ওপজেক্টিভ-সি পদ্ধতিতে আপনি এটি সব করতে না পারার কোনও কারণ নেই।
wbyoung

12

প্রথমে আমি পদ্ধতির সুইজলিংয়ের দ্বারা আমি কী বোঝাতে চাইছি ঠিক তা সংজ্ঞায়িত করব:

  • মূলত একটি পদ্ধতিতে (এ বলা হয়) একটি নতুন পদ্ধতিতে (বি নামে পরিচিত) প্রেরিত সমস্ত কলকে পুনরায় রাউটিং করা।
  • আমরা মেথড বি
  • আমরা নিজস্ব পদ্ধতি এ
  • পদ্ধতি বি কিছু কাজ করে তারপর পদ্ধতি এ কল করে A.

এর চেয়ে মেথড সুইজলিং বেশি সাধারণ তবে আমি আগ্রহী এই ক্ষেত্রে এটি।

বিপদ:

  • মূল শ্রেণিতে পরিবর্তন । আমরা যে ক্লাসে সুইজ করছি তার মালিকানা আমাদের নেই। ক্লাস পরিবর্তন হলে আমাদের সুইজল কাজ করা বন্ধ করতে পারে।

  • বজায় রাখা শক্ত । আপনি কেবল সুইজল পদ্ধতি লিখতে এবং বজায় রাখতে পারেন নি। আপনাকে সুইডলটি সংঘটিত করার কোডটি লিখতে হবে এবং বজায় রাখতে হবে

  • ডিবাগ করা শক্ত । একটি ঘূর্ণিঝড়ের প্রবাহ অনুসরণ করা শক্ত, কিছু লোক এমনকি বুঝতে পারে না যে সুইজলটি আগে থেকেই তৈরি করা হয়েছে। যদি সুইজল থেকে প্রবর্তিত ত্রুটি রয়েছে (সম্ভবত মূল শ্রেণীর পরিবর্তনের জন্য পাওনা আছে) তবে তাদের সমাধান করা শক্ত হবে।

সংক্ষেপে, আপনার কমপক্ষে সুইজলিং রাখা উচিত এবং বিবেচনা করা উচিত যে মূল শ্রেণীর পরিবর্তনগুলি আপনার সুইজলে কীভাবে প্রভাব ফেলতে পারে। এছাড়াও আপনি স্পষ্টভাবে মন্তব্য এবং ডকুমেন্ট করা উচিত যা আপনি করছেন (বা কেবল এটি পুরোপুরি এড়ানো)।


@ প্রত্যেকটি আমি আপনার উত্তরগুলি একটি সুন্দর বিন্যাসে সংযুক্ত করেছি। এটিকে সম্পাদনা / যুক্ত করতে নির্দ্বিধায় আপনার ইনপুট জন্য ধন্যবাদ।
রবার্ট

আমি আপনার মনোবিজ্ঞানের একজন ভক্ত। "দুর্দান্ত সুইজলিং পাওয়ার সাথে দুর্দান্ত সুইজলিংয়ের দায়িত্ব আসে" "
জ্যাকসনকর

7

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


আমি বলব যে এই জাতীয় দেবগণ যা বপন করেন তার ফসল কাটাতে হবে - তারা দৃ code়তার সাথে তাদের কোডটি একটি বিশেষ প্রয়োগের সাথে সংযুক্ত করলেন। সুতরাং তাদের ত্রুটি যদি এই বাস্তবায়ন একটি সূক্ষ্মভাবে পরিবর্তিত হয় যে তাদের কোডটি ভঙ্গ না করা উচিত ছিল যদি না তারা তাদের কোডের মতো কঠোরভাবে সংযুক্ত করার সুস্পষ্ট সিদ্ধান্ত না নেয়।
আরাফাঙ্গিয়ন

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

অ্যাপল কেবলমাত্র বেস ক্লাসগুলির সরবরাহকারী নয় যা সিউজলিংয়ের মাধ্যমে সংশোধন করা যায়। আপনার উত্তরটি প্রত্যেককে অন্তর্ভুক্ত করার জন্য সম্পাদনা করা উচিত।
এআর

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

পদ্ধতি সুইজলিং বিপজ্জনক হতে পারে। ফ্রেমওয়ার্কগুলি বের হওয়ার সাথে সাথে তারা পূর্বেরগুলিকে পুরোপুরি বাদ দেয় না। আপনার অ্যাপটি প্রত্যাশা করে এমন বেস ফ্রেমওয়ার্কটি আপনাকে এখনও আপডেট করতে হবে। এবং সেই আপডেটটি আপনার অ্যাপ্লিকেশনটিকে ভেঙে দেবে। আইওএস আপডেট হওয়ার পরে সমস্যাটি এত বড় হওয়ার কারণ না। আমার ব্যবহারের প্যাটার্নটি হ'ল ডিফল্ট পুনরায় ব্যবহারকার্য আইডেন্টিফায়ারকে ওভাররাইড করা। যেহেতু _reuseIdentifier ভেরিয়েবলটিতে আমার অ্যাক্সেস ছিল না এবং এটি প্রতিস্থাপন করতে চাই না যদি না এটি সরবরাহ করা হয় তবে আমার একমাত্র সমাধানটি ছিল প্রত্যেককে সাবক্লাস করা এবং পুনরায় ব্যবহারকারীর শনাক্তকরণ সরবরাহ করা, বা ঝাপটানো এবং শূন্য হলে ওভাররাইড। প্রয়োগের
ধরণটি

5

সতর্কতার সাথে এবং বুদ্ধিমানের সাথে ব্যবহার করা, এটি মার্জিত কোডের দিকে নিয়ে যেতে পারে, তবে সাধারণত এটি বিভ্রান্তিকর কোডে বাড়ে।

আমি বলছি যে এটি নিষিদ্ধ করা উচিত, যদি না আপনি না জেনে থাকেন যে এটি কোনও নির্দিষ্ট ডিজাইনের কোনও কাজের জন্য একটি খুব মার্জিত সুযোগ উপস্থাপিত করে তবে আপনার পরিস্থিতিটি কেন এটি ভালভাবে প্রযোজ্য, এবং কেন বিকল্পগুলির জন্য পরিস্থিতির জন্য মার্জিতভাবে কাজ হয় না তা আপনাকে পরিষ্কারভাবে জানা দরকার know ।

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

একটি খারাপ উদাহরণ হতে পারে আপনার ক্লাসগুলি বাড়ানোর উপায় হিসাবে পদ্ধতি সুইজলিংয়ের উপর নির্ভর করে যা চূড়ান্তভাবে সংযুক্ত হওয়ার দিকে পরিচালিত করে।


1
-1 প্রেক্ষাপটে KVO অফ উল্লেখ করার জন্য পদ্ধতি swizzling । ইসা সুইজলিং হ'ল অন্য কিছু।
নিকোলাই রুহে

@ নিকোলাইরুহে: দয়া করে রেফারেন্স সরবরাহ করতে দ্বিধা বোধ করুন যাতে আমি আলোকিত হতে পারি।
আরাফাঙ্গিয়ান


5

যদিও আমি এই কৌশলটি ব্যবহার করেছি, তবে আমি তা উল্লেখ করতে চাই:

  • এটি আপনার কোডটিকে অস্পষ্ট করে কারণ এটি অন-ডকুমেন্টেড, যদিও ইচ্ছুক, পার্শ্ব প্রতিক্রিয়া সৃষ্টি করতে পারে। যখন কেউ কোড পড়েন তখন তিনি যে সাইড এফেক্ট আচরণের প্রয়োজন তা অজানা থাকতে পারে যতক্ষণ না সে / যদি সে কোডটি বেসে সজ্জিত না হয় তা সন্ধান করতে ভুলে যায় না it আমি কীভাবে এই সমস্যাটি দূর করতে পারি তা নিশ্চিত নই কারণ কোডটি সাইড এফেক্ট সুইজলড আচরণের উপর নির্ভরশীল এমন সমস্ত জায়গার নথিভুক্ত করা সর্বদা সম্ভব নয়।
  • এটি আপনার কোডকে কম পুনঃব্যবহারযোগ্য করে তুলতে পারে কারণ যে কেউ যদি এমন কোনও কোডের অংশ খুঁজে পান যা সুইজড আচরণের উপর নির্ভর করে যা তারা অন্য কোথাও ব্যবহার করতে চান তবে সুইজল পদ্ধতিটি খুঁজে না পেয়ে এবং অনুলিপি না করে কেবল এটিকে অন্য কোনও কোড বেসে আটকানো যাবে না।

4

আমি অনুভব করি যে সবচেয়ে বড় বিপদটি হ'ল সম্পূর্ণ দুর্ঘটনাক্রমে অনেকগুলি অযাচিত পার্শ্ব প্রতিক্রিয়া তৈরি করা। এই পার্শ্ব প্রতিক্রিয়াগুলি নিজেকে 'বাগ' হিসাবে উপস্থাপন করতে পারে যা ফলস্বরূপ সমাধান খুঁজতে আপনাকে ভুল পথে নামিয়ে দেয়। আমার অভিজ্ঞতায়, বিপদটি অযৌক্তিক, বিভ্রান্তিকর এবং হতাশার কোড। কেউ যখন সি ++ এ ফাংশন পয়েন্টারগুলিকে অতিরিক্ত ব্যবহার করে তখন এ জাতীয় ধরনের।


ঠিক আছে, সুতরাং সমস্যাটি হ'ল এটি ডিবাগ করা শক্ত। সমস্যাগুলি হ'ল কারণ পর্যালোচকেরা বুঝতে পারেন না / ভুলে যান যে কোডটি সুইজল হয়ে গেছে এবং ডিবাগ করার সময় ভুল জায়গায় খুঁজছেন।
রবার্ট

3
হ্যাঁ বেশ। এছাড়াও, অতিরিক্ত ব্যবহারের সময় আপনি একটি অন্তহীন চেইন বা সুইজলের ওয়েব এ যেতে পারেন। ভাবুন আপনি যখন ভবিষ্যতের কিছু মুহুর্তে তাদের মধ্যে একটির পরিবর্তন করেন তখন কী ঘটতে পারে? আমি অভিজ্ঞতাকে স্ট্যাকিং টিচার বা 'কোড জেঙ্গা' খেলার সাথে তুলনা করেছি
এআর

4

আপনি বিজোড় খুঁজছেন কোড মত শেষ হতে পারে

- (void)addSubview:(UIView *)view atIndex:(NSInteger)index {
    //this looks like an infinite loop but we're swizzling so default will get called
    [self addSubview:view atIndex:index];

কিছু ইউআই ম্যাজিক সম্পর্কিত প্রকৃত উত্পাদন কোড থেকে।


3

ইউনিট টেস্টিংয়ে পদ্ধতিটি সুইজলিং খুব সহায়ক হতে পারে।

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


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