আমার অবজেক্টিভ সি সিঙ্গলটন দেখতে কেমন হবে? [বন্ধ]


334

আমার সিঙ্গলটন অ্যাকসেসর পদ্ধতিটি সাধারণত এর কিছু বৈকল্পিক:

static MyClass *gInstance = NULL;

+ (MyClass *)instance
{
    @synchronized(self)
    {
        if (gInstance == NULL)
            gInstance = [[self alloc] init];
    }

    return(gInstance);
}

আমি এর উন্নতি করতে কি করতে পারি?


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

যেহেতু খুব শীঘ্রই এই প্রশ্নের 'উত্তর' যে কোনও সময় পরিবর্তিত হবে এটি অসম্ভব, তাই আমি প্রশ্নটিতে একটি historicalতিহাসিক লক রাখছি। দুটি কারণ ১) প্রচুর ভিউ, ভোট এবং ভাল সামগ্রী 2) উন্মুক্ত / বন্ধ হওয়াতে ইয়ো-ইয়িং প্রতিরোধ করতে। এটি তার সময়ের জন্য দুর্দান্ত প্রশ্ন ছিল তবে স্ট্যাক ওভারফ্লোয়ের জন্য এই ধরণের প্রশ্নগুলি উপযুক্ত নয়। ওয়ার্কিং কোড চেক করার জন্য আমাদের কাছে এখন কোড রিভিউ রয়েছেএই মেটা প্রশ্নে দয়া করে এই প্রশ্নের সমস্ত আলোচনা করুন ।
জর্জ স্টকার

উত্তর:


207

আরেকটি বিকল্প হ'ল +(void)initializeপদ্ধতিটি ব্যবহার করা । ডকুমেন্টেশন থেকে:

রানটাইম initializeক্লাসের ঠিক এক সময়ের আগেই একটি প্রোগ্রামে প্রতিটি ক্লাসে প্রেরণ করে, বা যে শ্রেণী থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় তাকে প্রোগ্রামের মধ্যে থেকেই তার প্রথম বার্তা পাঠানো হয়। (সুতরাং ক্লাসটি ব্যবহার না করা হলে পদ্ধতিটি কখনই ডাকা যাবে না)) রানটাইম initializeক্লাসগুলিকে থ্রেড-নিরাপদ উপায়ে বার্তা প্রেরণ করে । সুপারক্লাসগুলি তাদের সাবক্লাসের আগে এই বার্তাটি গ্রহণ করে।

সুতরাং আপনি এর সদৃশ কিছু করতে পারেন:

static MySingleton *sharedSingleton;

+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        sharedSingleton = [[MySingleton alloc] init];
    }
}

7
যদি রানটাইম কেবল একবার কল করে, বোল কী করে? কেউ যদি তাদের কোড থেকে এই ফাংশনটি স্পষ্টভাবে কল করে তবে কি এটি একটি সাবধানতা?
পরের

5
হ্যাঁ, এটি একটি সতর্কতা যেহেতু ফাংশনটিকে সরাসরি ডাকাও যায়।
রবি হ্যানসন

33
এটিও প্রয়োজন কারণ সাবক্ল্যাস থাকতে পারে। তারা যদি ওভাররাইড না করে +initializeতবে সাবক্লাসটি প্রথম ব্যবহার করা হলে তাদের সুপারক্লাস বাস্তবায়ন ডাকা হবে।
শে

3
@ পল আপনি releaseপদ্ধতিটি ওভাররাইড করে এটিকে খালি করতে পারবেন । :)

4
@aryaxt: তালিকাভুক্ত ডক্স থেকে, এটি ইতিমধ্যে থ্রেড নিরাপদ। সুতরাং, কলটি একবার রানটাইম - পিরিয়ডের জন্য একবার। এটি সঠিক, থ্রেড-নিরাপদ, সর্বোত্তম দক্ষ সমাধান বলে মনে হবে।
লিলবির্ডি

95
@interface MySingleton : NSObject
{
}

+ (MySingleton *)sharedSingleton;
@end

@implementation MySingleton

+ (MySingleton *)sharedSingleton
{
  static MySingleton *sharedSingleton;

  @synchronized(self)
  {
    if (!sharedSingleton)
      sharedSingleton = [[MySingleton alloc] init];

    return sharedSingleton;
  }
}

@end

[সূত্র]


7
আপনার সাধারণত সিঙ্গলটনের জন্য ব্যবহার করা উচিত। অন্যান্য জিনিসের মধ্যে আপনার ক্লাসগুলি পৃথকভাবে তাত্ক্ষণিক রাখার ফলে তাদের পরীক্ষা করা সহজ হয়, কারণ আপনি তাদের অবস্থা পুনরায় সেট করার পরিবর্তে পৃথক দৃষ্টান্ত পরীক্ষা করতে পারেন।
ক্রিস হ্যানসন

3
স্টিগ ব্রুটাসেট: না, এই উদাহরণে @ সিনক্রোনাইজডকে ছেড়ে দেওয়া ঠিক হবে না। এই স্থিতিশীল ফাংশনটি একই সাথে কার্যকর করার জন্য দুটি থ্রেডের সম্ভাব্য রেস-কন্ডিশন পরিচালনা করতে হবে, উভয় একই সাথে "যদি (! শেয়ারডসিংটন)" পরীক্ষায় উত্তীর্ণ হয় এবং ফলস্বরূপ দুটি [মাইসিংটন এলেক্ট] এস হয়। .. @ সিনক্রোনাইজড {স্কোপ ব্লক} যে অনুমানকৃত দ্বিতীয় থ্রেডটিকে এগিয়ে যাওয়ার অনুমতি দেওয়ার আগে thread স্কোপ ব্লক exit থেকে বেরিয়ে যাওয়ার জন্য প্রথম থ্রেডের জন্য অপেক্ষা করতে বাধ্য করে। আশা করি এটা কাজে লাগবে! =)
মেচ ইথান

3
কাউকে এখনও অবজেক্টটির নিজস্ব উদাহরণ তৈরি করতে বাধা দেয়? MySingleton *s = [[MySingelton alloc] init];
লিন্ডন শিয়াল

1
@ লিন্ডনফক্স আপনার প্রশ্নের উত্তর কী?
রাফি খাঁচাডোরিয়ান

1
@ রাফি - দুঃখিত আমি মনে করি আমি অবশ্যই আমার উত্তরে পেস্ট করতে ভুলে গেছি। যাইহোক, আমি বইটি পেয়েছি Pro Objective-C Design Patterns for iOSএবং এটি কীভাবে আপনি "কঠোর" সিনগেলটন তৈরি করেন তা ব্যাখ্যা করে। মূলত যেহেতু আপনি আরম্ভের পদ্ধতিগুলিকে ব্যক্তিগত করতে পারবেন না, তাই আপনাকে বরাদ্দ করা এবং অনুলিপিগুলি বাতিল করতে হবে। সুতরাং যদি আপনি চেষ্টা করে কিছু করেন তবে আপনি [[MySingelton alloc] init]রান টাইম ত্রুটি পাবেন (যদিও দুর্ভাগ্যক্রমে সংকলনের সময় ত্রুটি নয়)। আমি কীভাবে অবজেক্ট তৈরির সমস্ত বিবরণ বুঝতে পারি না তবে আপনি + (id) allocWithZone:(NSZone *)zoneযা প্রয়োগ করেন তা বাস্তবায়ন করেনsharedSingleton
লিন্ডন ফক্স

59

নীচে আমার অন্য উত্তর অনুসারে, আমার মনে হয় আপনার করা উচিত:

+ (id)sharedFoo
{
    static dispatch_once_t once;
    static MyFoo *sharedFoo;
    dispatch_once(&once, ^ { sharedFoo = [[self alloc] init]; });
    return sharedFoo;
}

6
আপনি উপরের যা করছেন তা নিয়ে মাথা ঘামান না। আপনার (আশাবাদী খুব কম) সিঙ্গেলনগুলি পৃথক-তাত্ক্ষণিক করে তুলুন এবং কেবল একটি ভাগ / ডিফল্ট পদ্ধতি করুন। আপনি যা করেছেন তা কেবলমাত্র প্রয়োজনীয় যদি আপনি সত্যই সত্যই কেবল আপনার শ্রেণীর একক উদাহরণ চান। যা আপনি না, esp। ইউনিট পরীক্ষার জন্য।
ক্রিস হ্যানসন

জিনিসটি হ'ল "একটি সিঙ্গলটন তৈরি করার" জন্য অ্যাপল স্যাম্পল কোড। তবে হ্যাঁ, আপনি একেবারে ঠিক বলেছেন।
কলিন ব্যারেট

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

উপরোক্ত পদ্ধতির জন্য এখানে একটি ম্যাক্রো দেওয়া হয়েছে: gist.github.com/1057420 । এটিই আমি ব্যবহার করি।
কোবস্কি

1
ইউনিট একপাশে পরীক্ষা, এই সমাধানের বিরুদ্ধে কথা বলার কিছুই নেই, তাই না? এবং এটি দ্রুত এবং নিরাপদ।
শিখুন কোকোস

58

যেহেতু কেন্ডাল একটি থ্রেডসেফ সিঙ্গলটন পোস্ট করেছে যা লকিং ব্যয় এড়ানোর চেষ্টা করে, তাই আমি ভেবেছিলাম যে আমিও একটি টস করব:

#import <libkern/OSAtomic.h>

static void * volatile sharedInstance = nil;                                                

+ (className *) sharedInstance {                                                                    
  while (!sharedInstance) {                                                                          
    className *temp = [[self alloc] init];                                                                 
    if(!OSAtomicCompareAndSwapPtrBarrier(0x0, temp, &sharedInstance)) {
      [temp release];                                                                                   
    }                                                                                                    
  }                                                                                                        
  return sharedInstance;                                                                        
}

ঠিক আছে, আমাকে কীভাবে এটি কাজ করে তা বোঝাতে:

  1. দ্রুত ক্ষেত্রে: সাধারণ সম্পাদন sharedInstanceইতিমধ্যে সেট হয়ে গেছে, সুতরাং whileলুপ কখনও কার্যকর করা হয় না এবং ভেরিয়েবলের অস্তিত্বের জন্য পরীক্ষা করার পরে ফাংশনটি ফিরে আসে;

  2. ধীর কেস: যদি sharedInstanceঅস্তিত্ব না থাকে, তবে একটি তুলনা ও স্বাপ ('সিএএস') ব্যবহার করে একটি উদাহরণ বরাদ্দ করা হয় এবং এতে অনুলিপি করা হয়;

  3. তর্ক ক্ষেত্রে: দুই থ্রেড কলে উভয় প্রয়াস যদি sharedInstanceএকই সময়ে এবং sharedInstance একই সময়ে বিদ্যমান নয় তারপর তারা Singleton উভয় আরম্ভ নতুন দৃষ্টান্ত এবং অবস্থান সেটিকে সি এ এস করার চেষ্টা করবে। যে কোনও জিতে সিএএস তত্ক্ষণাত্ রিটার্ন জিতে নেয়, যেটি হারিয়ে যায় তার যেটি কেবলমাত্র বরাদ্দ করা ইভেন্টটি রিলিজ করে এবং (এখন সেট) প্রদান করে sharedInstance। এককটি OSAtomicCompareAndSwapPtrBarrierসেটিংস থ্রেডের জন্য লেখার বাধা এবং পরীক্ষার থ্রেড থেকে পঠন প্রতিবন্ধক উভয় হিসাবে কাজ করে।


18
এটি কোনও অ্যাপ্লিকেশনটির জীবদ্দশায় সবচেয়ে বেশি একবারের জন্য সম্পূর্ণ ওভারকিল। তবুও, এটি স্পট-অন সঠিক, এবং তুলনা-এবং-অদলবদ কৌশলটি সম্পর্কে জানতে একটি দরকারী সরঞ্জাম, সুতরাং +1।
স্টিভ ম্যাডসেন

উত্তম উত্তর - OSAtomic পরিবার সম্পর্কে জানার জন্য একটি ভাল জিনিস
বিল

1
@ লুইস: আশ্চর্যজনক, সত্যই আলোকিত উত্তর! যদিও একটি প্রশ্ন: initআপনার পদ্ধতিতে আমার পদ্ধতিটি কী করা উচিত ? sharedInstanceআমি প্রাথমিকভাবে যখন ব্যতিক্রম শুরু করা ভাল ধারণা নয়, আমি বিশ্বাস করি, initসরাসরি বহুবার ব্যবহারকারীর কলিং রোধ করতে তখন কী করবেন ?
ম্যাথাম

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

1
@ প্রতিক্রিয়া থেকে বেশ কয়েক দেরী হলেও OSAtomicCompareAndSwapPtrBarrier এর একটি অস্থিরতা প্রয়োজন। সম্ভবত উদ্বায়ী কীওয়ার্ডটি চেকটিকে অপ্টিমাইজ করা থেকে সংকলককে রাখা? দেখুন: স্ট্যাকওভারফ্লো.com / a / 5334727 / 449161 এবং বিকাশকারী
বেন ফ্লাইন

14
স্ট্যাটিক মাইক্লাস * শেয়ারডইনস্ট = শূন্য;

+ (আইডি) শেয়ার করা ইনস্ট্যান্স
{
    @ সিনক্রোনাইজ (স্ব) {
        যদি (শেয়ারড ইনস্ট == শূন্য) {
            / * শেয়ারডইনস্টে সেট আপ * /
            [[স্ব বরাদ্দ] init];
        }
    }
    শেয়ারড ইনস্টার্ড;
}

- (আইডি) init
{
    যদি (শেয়ারডইনস্ট! = শূন্য) {
        [এনএসইসেপশন উত্থাপন: এনএসইটার্নাল ইনকনসিসটেন্সি এক্সেক্সেশন
            ফর্ম্যাট: @ "[% @% @] বলা যাবে না; পরিবর্তে + [% @% @] ব্যবহার করুন]],
            এনএসএসস্ট্রিংফ্রমক্লাস ([স্ব শ্রেণি]), এনএসএস স্ট্রিংফ্রোমস্লেক (_সিএমডি), 
            এনএসএস স্ট্রিংফ্রমক্লাস ([স্ব শ্রেণি]),
            NSStringFromSelector (@selector (sharedInstance) "];
    } অন্যথায় যদি (স্ব = [সুপার থিম]) {
        শেয়ারড ইনস্ট = স্ব;
        / * এখানে শ্রেণি নির্দিষ্ট যাই হোক না কেন * /
    }
    শেয়ারড ইনস্টার্ড;
}

/ * এগুলি সম্ভবত কিছুই করে না
   একটি জিসি অ্যাপ্লিকেশন। সিঙ্গলটন রাখে
   এ হিসাবে একটি আসল একক হিসাবে
   নন সিজি অ্যাপ্লিকেশন
* /
- (NSUInteger) রক্ষণাবেক্ষণ
{
    NSUIntegerMax প্রদান;
}

- (একদম শূন্য) মুক্তি
{
}

- (আইডি) ধরে রাখা
{
    শেয়ারড ইনস্টার্ড;
}

- (আইডি)
{
    শেয়ারড ইনস্টার্ড;
}

3
আমি লক্ষ্য করেছি যে [[self alloc] init]ঝাঁকুনি একটি ফাঁস সম্পর্কে অভিযোগ করে যদি আপনি শেয়ারড ইনস্টের ফলাফল নির্ধারণ না করেন ।
pix0r

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

12

সম্পাদনা: এই বাস্তবায়নটি এআরসি দিয়ে অচল। দয়া করে এক নজরে দেখুন কীভাবে আমি একটি ওজেক্টিভ সি সিঙ্গলটন প্রয়োগ করব যা এটিআরসি সাথে সামঞ্জস্যপূর্ণ? সঠিক বাস্তবায়নের জন্য।

আমি অন্যান্য উত্তরে পড়েছি আরম্ভের সমস্ত বাস্তবায়ন একটি সাধারণ ত্রুটি ভাগ করে।

+ (void) initialize {
  _instance = [[MySingletonClass alloc] init] // <----- Wrong!
}

+ (void) initialize {
  if (self == [MySingletonClass class]){ // <----- Correct!
      _instance = [[MySingletonClass alloc] init] 
  }
}

অ্যাপল ডকুমেন্টেশন আপনাকে আপনার প্রারম্ভিক ব্লকটিতে শ্রেণীর ধরণের পরীক্ষা করার পরামর্শ দেয়। কারণ সাবক্লাসগুলি ডিফল্টরূপে আরম্ভকে কল করে। অপ্রকাশ্য একটি কেস রয়েছে যেখানে কেভিওর মাধ্যমে পরোক্ষভাবে সাবক্ল্যাস তৈরি করা যেতে পারে। আপনি যদি অন্য ক্লাসে নিম্নলিখিত লাইনটি যুক্ত করেন তবে:

[[MySingletonClass getInstance] addObserver:self forKeyPath:@"foo" options:0 context:nil]

অবজেক্টিভ-সি সুস্পষ্টভাবে মাইসিংলেটনক্লাসের একটি সাবক্লাস তৈরি করবে যার ফলস্বরূপ দ্বিতীয়টি ট্রিগার হবে +initialize

আপনি ভাবতে পারেন যে আপনার ইন ব্লকে সদৃশভাবে সদৃশভাবে পরীক্ষা করা উচিত:

- (id) init { <----- Wrong!
   if (_instance != nil) {
      // Some hack
   }
   else {
      // Do stuff
   }
  return self;
}

তবে আপনি নিজেকে পায়ে গুলি করবেন; বা আরও খারাপ অন্য কোনও বিকাশকারীকে তাদের পায়ে গুলি করার সুযোগ দিন।

- (id) init { <----- Correct!
   NSAssert(_instance == nil, @"Duplication initialization of singleton");
   self = [super init];
   if (self){
      // Do stuff
   }
   return self;
}

টিএল; ডিআর, আমার বাস্তবায়ন এখানে

@implementation MySingletonClass
static MySingletonClass * _instance;
+ (void) initialize {
   if (self == [MySingletonClass class]){
      _instance = [[MySingletonClass alloc] init];
   }
}

- (id) init {
   ZAssert (_instance == nil, @"Duplication initialization of singleton");
   self = [super init];
   if (self) {
      // Initialization
   }
   return self;
}

+ (id) getInstance {
   return _instance;
}
@end

(আমাদের নিজস্ব জোর ম্যাক্রোর সাথে জেডএসার্ট প্রতিস্থাপন করুন; বা কেবল এনএসএসর্ট করুন sert)


1
আমি কেবল সহজভাবে বেঁচে থাকব এবং পুরোপুরি প্রাথমিকভাবে এড়াতে চাই।
টম অ্যান্ডারসন


9

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

// Volatile to make sure we are not foiled by CPU caches
static volatile ALBackendRequestManager *sharedInstance;

// There's no need to call this directly, as method swizzling in sharedInstance
// means this will get called after the singleton is initialized.
+ (MySingleton *)simpleSharedInstance
{
    return (MySingleton *)sharedInstance;
}

+ (MySingleton*)sharedInstance
{
    @synchronized(self)
    {
        if (sharedInstance == nil)
        {
            sharedInstance = [[MySingleton alloc] init];
            // Replace expensive thread-safe method 
            // with the simpler one that just returns the allocated instance.
            SEL origSel = @selector(sharedInstance);
            SEL newSel = @selector(simpleSharedInstance);
            Method origMethod = class_getClassMethod(self, origSel);
            Method newMethod = class_getClassMethod(self, newSel);
            method_exchangeImplementations(origMethod, newMethod);
        }
    }
    return (MySingleton *)sharedInstance;
}

1
এটি +1 সত্যিই আকর্ষণীয়। আমি একটি ক্লোন class_replaceMethodরূপান্তর করতে ব্যবহার করতে পারেন । এইভাবে আপনাকে আর কোনও লক অর্জনের বিষয়ে চিন্তা করতে হবে না । sharedInstancesimpleSharedInstance@synchronized
ডেভ দেলং

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

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

আপনি একটি থ্রেড নিরাপদ সংস্করণ তৈরি করতে পারেন যা রিকটাইম মাকিংয়ের গুচ্ছ না করে প্রারম্ভিককরণের পরে লকিংয়ের মূল্য পরিশোধ করে না, আমি নীচে একটি বাস্তবায়ন পোস্ট করেছি।
লুই গারবার্গ

1
+1 দুর্দান্ত ধারণা। আমি রানটাইমের সাথে যেগুলি করতে পারি সেগুলি কেবলই আমি পছন্দ করি। তবে বেশিরভাগ ক্ষেত্রে এটি সম্ভবত অকাল অপটিমাইজেশন। যদি আমি সত্যিই সিঙ্ক্রোনাইজেশন ব্যয় থেকে মুক্তি পেতে পারি তবে আমি সম্ভবত লুই দ্বারা লকলেস সংস্করণটি ব্যবহার করতাম।
সেভেন

6

সংক্ষিপ্ত উত্তর: চমত্কার।

দীর্ঘ উত্তর: এরকম কিছু ....

static SomeSingleton *instance = NULL;

@implementation SomeSingleton

+ (id) instance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == NULL){
            instance = [[super allocWithZone:NULL] init];
        }
    });
    return instance;
}

+ (id) allocWithZone:(NSZone *)paramZone {
    return [[self instance] retain];
}

- (id) copyWithZone:(NSZone *)paramZone {
    return self;
}

- (id) autorelease {
    return self;
}

- (NSUInteger) retainCount {
    return NSUIntegerMax;
}

- (id) retain {
    return self;
}

@end

কী চলছে তা বুঝতে শিরোনামটি একবার / পাঠাতে ভুলবেন না read এই ক্ষেত্রে শিরোনামের মন্তব্যগুলি ডক্স বা ম্যান পৃষ্ঠার চেয়ে বেশি প্রযোজ্য।


5

আমি সিঙ্গেলটনকে একটি ক্লাসে রোল করেছি, যাতে অন্যান্য ক্লাসগুলি সিঙ্গেলটন বৈশিষ্ট্যের অধিকারী হতে পারে can

সিঙ্গলটন এইচ:

static id sharedInstance = nil;

#define DEFINE_SHARED_INSTANCE + (id) sharedInstance {  return [self sharedInstance:&sharedInstance]; } \
                               + (id) allocWithZone:(NSZone *)zone { return [self allocWithZone:zone forInstance:&sharedInstance]; }

@interface Singleton : NSObject {

}

+ (id) sharedInstance;
+ (id) sharedInstance:(id*)inst;

+ (id) allocWithZone:(NSZone *)zone forInstance:(id*)inst;

@end

সিঙ্গলটন.এম:

#import "Singleton.h"


@implementation Singleton


+ (id) sharedInstance { 
    return [self sharedInstance:&sharedInstance];
}

+ (id) sharedInstance:(id*)inst {
    @synchronized(self)
    {
        if (*inst == nil)
            *inst = [[self alloc] init];
    }
    return *inst;
}

+ (id) allocWithZone:(NSZone *)zone forInstance:(id*)inst {
    @synchronized(self) {
        if (*inst == nil) {
            *inst = [super allocWithZone:zone];
            return *inst;  // assignment and return on first allocation
        }
    }
    return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}


@end

এবং এখানে কিছু শ্রেণীর উদাহরণ দেওয়া হল যে আপনি সিঙ্গলটন হতে চান।

#import "Singleton.h"

@interface SomeClass : Singleton {

}

@end

@implementation SomeClass 

DEFINE_SHARED_INSTANCE;

@end

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


আপনি হয়ত অন্য কিছু লকিং মেকানিজম ব্যবহার করতে চাইতে পারেন কারণ @synchronizedমারাত্মক ধীর এবং এড়ানো উচিত should
ডার্কডাস্ট

2

এটি একটি আবর্জনা সংগ্রহ করা পরিবেশেও কাজ করে।

@interface MySingleton : NSObject {
}

+(MySingleton *)sharedManager;

@end


@implementation MySingleton

static MySingleton *sharedMySingleton = nil;

+(MySingleton*)sharedManager {
    @synchronized(self) {
        if (sharedMySingleton == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedMySingleton;
}


+(id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedMySingleton == nil) {
            sharedMySingleton = [super allocWithZone:zone];
            return sharedMySingleton;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}


-(void)dealloc {
    [super dealloc];
}

-(id)copyWithZone:(NSZone *)zone {
    return self;
}


-(id)retain {
    return self;
}


-(unsigned)retainCount {
    return UINT_MAX;  //denotes an object that cannot be release
}


-(void)release {
    //do nothing    
}


-(id)autorelease {
    return self;    
}


-(id)init {
    self = [super init];
    sharedMySingleton = self;

    //initialize here

    return self;
}

@end

2

এই থ্রেডসেফ হওয়া উচিত না এবং প্রথম কল করার পরে ব্যয়বহুল লকিং এড়ানো উচিত?

+ (MySingleton*)sharedInstance
{
    if (sharedInstance == nil) {
        @synchronized(self) {
            if (sharedInstance == nil) {
                sharedInstance = [[MySingleton alloc] init];
            }
        }
    }
    return (MySingleton *)sharedInstance;
}

2
এখানে ব্যবহৃত ডাবল- চেকড লকিং কৌশলটি প্রায়শই কিছু পরিবেশে আসল সমস্যা হয় (দেখুন aristeia.com / পেপারস / ডিডিজে_জুল_আগ_2004_ রিভিজড.পিডিএফ বা গুগল এটি)। অন্যথায় প্রদর্শিত না হওয়া পর্যন্ত, আমি ধরে নিয়েছি যে উদ্দেশ্য-সি প্রতিরোধী নয়। এছাড়াও উইন্সেন্ট . com/এ / জ্ঞান- বেস / আর্কাইভস / ২০০6/০১/২০১৮ দেখুন
স্টিভ ম্যাডসেন

2

এই যে ম্যাক্রোটি আমি একসাথে রেখেছি:

http://github.com/cjhanson/Objective-C-Optimized-Singleton

এটি ম্যাট গ্যালাগার দ্বারা নির্মিত কাজের উপর ভিত্তি করে তবে গুগলের ডেভ ম্যাকল্যাচলান বর্ণিত পদ্ধতি অনুসারে সুইজলিংয়ের ব্যবহারের বাস্তবায়ন পরিবর্তন করছেন ।

আমি মন্তব্য / অবদান স্বাগত জানাই।


লিঙ্কটি ভাঙ্গা মনে হচ্ছে - আমি কোথায় এই উত্স পেতে পারি?
amok

2

কেমন

static MyClass *gInstance = NULL;

+ (MyClass *)instance
{
    if (gInstance == NULL) {
        @synchronized(self)
        {
            if (gInstance == NULL)
                gInstance = [[self alloc] init];
        }
    }

    return(gInstance);
}

সুতরাং আপনি আরম্ভের পরে সিঙ্ক্রোনাইজেশন ব্যয় এড়াতে চান?


অন্যান্য উত্তরে ডুয়াল চেকড লক করার আলোচনা দেখুন।
আই_আম_জোরফ


1

কেএলসিংলেটন হ'ল:

  1. সাবক্লাসিবল (এন-ডিগ্রি ডিগ্রি পর্যন্ত)
  2. এআরসি সামঞ্জস্যপূর্ণ
  3. নিরাপদে allocএবংinit
  4. অলসভাবে বোঝা
  5. শংকা মুক্ত
  6. লক-ফ্রি (সিঙ্ক্রোনাইজ নয়, ব্যবহার + আরম্ভকরণ)
  7. ম্যাক্রো-মুক্ত
  8. পাঁচমিশালী মদ্যবিশেষ মুক্ত
  9. সহজ

KLSingleton


1
আমি আমার প্রকল্পের জন্য আপনার এনএসএসিংটন ব্যবহার করছি এবং এটি কেভিওর সাথে বেমানান বলে মনে হচ্ছে। বিষয় যা KVO এটা prefixing NSKVONotifying_ প্রতি KVO বস্তুর জন্য উপশ্রেণী সৃষ্টি করে MyClass । এবং এটি মাইক্লাসকে + আরম্ভ করে এবং -init পদ্ধতিগুলিকে দুইবার কল করা যায়।
ওলেগ ট্রাখম্যান

আমি এটি সর্বশেষতম এক্সকোডে পরীক্ষা করেছি এবং কেভিও ইভেন্টগুলির জন্য নিবন্ধকরণ বা গ্রহণ করতে কোনও সমস্যা হয়নি। আপনি নিম্নলিখিত কোডটি দিয়ে এটি যাচাই করতে পারেন: gist.github.com/3065038 আমি টুইটারে যেমন উল্লেখ করেছি, + আরম্ভের পদ্ধতিগুলি এনএসএসিংলেটনের জন্য একবার এবং প্রতিটি সাবক্লাসের জন্য একবার কল করা হয়। এটি অবজেক্টিভ-সি এর সম্পত্তি।
কেভিনল্লার

আপনি যদি পদ্ধতিটিতে যুক্ত NSLog(@"initialize: %@", NSStringFromClass([self class]));হন তবে +initializeআপনি যাচাই করতে পারবেন যে ক্লাসগুলি একবারই শুরু হয়েছিল।
কেভিনল্লার

এনএসএলগ (@ "ইনিশিয়াল:% @", এনএসএসস্ট্রিংফ্রমক্লাস ([স্ব শ্রেণি]));
ওলেগ ট্রাখমান

আপনি এটি আইবি সামঞ্জস্যপূর্ণ হতে চাইবেন। : খনি stackoverflow.com/questions/4609609/...
ড্যান Rosenstark

0

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

@implementation MYSingleton

static MYSingleton * sharedInstance = nil;

+( id )sharedInstance {
    @synchronized( [ MYSingleton class ] ) {
        if( sharedInstance == nil )
            sharedInstance = [ [ MYSingleton alloc ] init ];
    }

    return sharedInstance;
}

+( id )allocWithZone:( NSZone * )zone {
    @synchronized( [ MYSingleton class ] ) {
        if( sharedInstance == nil )
            sharedInstance = [ super allocWithZone:zone ];
    }

    return sharedInstance;
}

-( id )init {
    @synchronized( [ MYSingleton class ] ) {
        self = [ super init ];
        if( self != nil ) {
            // Insert initialization code here
        }

        return self;
    }
}

@end

1
বাকি পদ্ধতিগুলি, অ্যাকসেসর পদ্ধতিগুলি, মিউটর পদ্ধতিগুলি ইত্যাদির স্বতে সিঙ্ক্রোনাইজ করা উচিত। সমস্ত শ্রেণি (+) পদ্ধতি এবং প্রারম্ভিক (এবং সম্ভবত -ডেলোক) শ্রেণীর অবজেক্টে সিঙ্ক্রোনাইজ করা উচিত। আপনি যদি অ্যাক্সেসর / মিউটর পদ্ধতির পরিবর্তে অবজেক্টিভ সি 2.0 বৈশিষ্ট্যগুলি ব্যবহার করেন তবে ম্যানুয়ালি সিঙ্ক হওয়া এড়াতে পারবেন। সমস্ত অবজেক্ট.প্রোপার্টি এবং অবজেক্ট.প্রোপার্টি = foo, স্বয়ংক্রিয়ভাবে স্বতে সিঙ্ক্রোনাইজ হয়।
রব ডটসন

3
আপনি কেন মনে করেন যে selfকোনও শ্রেণি পদ্ধতিতে এই বস্তুর অস্তিত্ব নেই তা দয়া করে ব্যাখ্যা করুন । রানটাইম নির্ধারণ করে যে কোন পদ্ধতির প্রয়োগটি selfপ্রতিটি পদ্ধতির (শ্রেণি বা উদাহরণ) হিসাবে প্রদান করে ঠিক সেই একই মানের উপর নির্ভর করে oke
স্বপ্নালঙ্কা

2
একটি বর্গ পদ্ধতি ভিতরে, self হয় বর্গ অবজেক্ট। এটি নিজে চেষ্টা করুন:#import <Foundation/Foundation.h> @interface Eggbert : NSObject + (BOOL) selfIsClassObject; @end @implementation Eggbert + (BOOL) selfIsClassObject { return self == [Eggbert class]; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSLog(@"%@", [Eggbert selfIsClassObject] ? @"YES" : @"NO"); [pool drain]; return 0; }
jscs

0

শুধু এটি এখানে ছেড়ে যেতে চেয়েছিলেন যাতে আমি এটি হারাতে পারি না। এর একটির সুবিধা হ'ল এটি ইন্টারফেসবিল্ডারে ব্যবহারযোগ্য, যা একটি বিশাল সুবিধা। এটি আমি জিজ্ঞাসা করা অন্য প্রশ্ন থেকে নেওয়া হয়েছে :

static Server *instance;

+ (Server *)instance { return instance; }

+ (id)hiddenAlloc
{
    return [super alloc];
}

+ (id)alloc
{
    return [[self instance] retain];
}


+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        instance = [[Server hiddenAlloc] init];
    }
}

- (id) init
{
    if (instance)
        return self;
    self = [super init];
    if (self != nil) {
        // whatever
    }
    return self;
}

0
static mySingleton *obj=nil;

@implementation mySingleton

-(id) init {
    if(obj != nil){     
        [self release];
        return obj;
    } else if(self = [super init]) {
        obj = self;
    }   
    return obj;
}

+(mySingleton*) getSharedInstance {
    @synchronized(self){
        if(obj == nil) {
            obj = [[mySingleton alloc] init];
        }
    }
    return obj;
}

- (id)retain {
    return self;
}

- (id)copy {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release {
    if(obj != self){
        [super release];
    }
    //do nothing
}

- (id)autorelease {
    return self;
}

-(void) dealloc {
    [super dealloc];
}
@end

0

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

আমি যে ম্যাক্রোগুলি লিখেছি সেগুলি আমি বেশ কয়েকটি ওবিজসি বাস্তবায়নের ভিত্তিতে লিখেছি।

Singeton.h

/**
 @abstract  Helps define the interface of a singleton.
 @param  TYPE  The type of this singleton.
 @param  NAME  The name of the singleton accessor.  Must match the name used in the implementation.
 @discussion
 Typcially the NAME is something like 'sharedThing' where 'Thing' is the prefix-removed type name of the class.
 */
#define SingletonInterface(TYPE, NAME) \
+ (TYPE *)NAME;


/**
 @abstract  Helps define the implementation of a singleton.
 @param  TYPE  The type of this singleton.
 @param  NAME  The name of the singleton accessor.  Must match the name used in the interface.
 @discussion
 Typcially the NAME is something like 'sharedThing' where 'Thing' is the prefix-removed type name of the class.
 */
#define SingletonImplementation(TYPE, NAME) \
static TYPE *__ ## NAME; \
\
\
+ (void)initialize \
{ \
    static BOOL initialized = NO; \
    if(!initialized) \
    { \
        initialized = YES; \
        __ ## NAME = [[TYPE alloc] init]; \
    } \
} \
\
\
+ (TYPE *)NAME \
{ \
    return __ ## NAME; \
}

ব্যবহারের উদাহরণ:

MyManager.h

@interface MyManager

SingletonInterface(MyManager, sharedManager);

// ...

@end

MyManager.m

@implementation MyManager

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

SingletonImplementation(MyManager, sharedManager);

// ...

@end

কেন একটি ইন্টারফেস ম্যাক্রো প্রায় খালি? শিরোনাম এবং কোড ফাইলগুলির মধ্যে কোডের ধারাবাহিকতা; আপনি আরও স্বয়ংক্রিয় পদ্ধতি যুক্ত করতে বা এটিকে প্রায় পরিবর্তন করতে চান ক্ষেত্রে রক্ষণাবেক্ষণযোগ্যতা।

আমি এখানে (লেখার সময়) সর্বাধিক জনপ্রিয় উত্তরে ব্যবহৃত সিঙ্গলটন তৈরির জন্য প্রাথমিক পদ্ধতিটি ব্যবহার করছি।


0

অবজেক্টিভ সি শ্রেণীর পদ্ধতিগুলির সাহায্যে আমরা কেবলমাত্র সিঙ্গেলটন প্যাটার্নটি স্বাভাবিক উপায়ে ব্যবহার করা এড়াতে পারি:

[[Librarian sharedInstance] openLibrary]

প্রতি:

[Librarian openLibrary]

ক্লাসটি অন্য ক্লাসের মধ্যে আবৃত করে যেখানে ক্লাস পদ্ধতি রয়েছে কেবল সেভাবে দুর্ঘটনাক্রমে সদৃশ উদাহরণ তৈরি করার কোনও সম্ভাবনা নেই, কারণ আমরা কোনও উদাহরণ তৈরি করছি না!

আমি এখানে আরও বিস্তারিত ব্লগ লিখেছিলাম :)


আপনার লিঙ্কটি আর কাজ করে না।
i_am_jorf

0

@ রবি-হ্যানসন থেকে উদাহরণটি প্রসারিত করতে ...

static MySingleton* sharedSingleton = nil;

+ (void)initialize {
    static BOOL initialized = NO;
    if (!initialized) {
        initialized = YES;
        sharedSingleton = [[self alloc] init];
    }
}

- (id)init {
    self = [super init];
    if (self) {
        // Member initialization here.
    }
    return self;
}

0

আমার উপায় এই মত সহজ:

static id instanceOfXXX = nil;

+ (id) sharedXXX
{
    static volatile BOOL initialized = NO;

    if (!initialized)
    {
        @synchronized([XXX class])
        {
            if (!initialized)
            {
                instanceOfXXX = [[XXX alloc] init];
                initialized = YES;
            }
        }
    }

    return instanceOfXXX;
}

যদি সিঙ্গেলটন ইতিমধ্যে ইনিশিয়াল করা হয় তবে লক ব্লক প্রবেশ করা হবে না। (! আরম্ভ করা) দ্বিতীয় চেকটি বর্তমান থ্রেডটি লকটি অর্জন করার সময় এটি আরম্ভ করা হয়নি তা নিশ্চিত করা হয় কিনা।


এটি চিহ্নিত initializedকরা volatileযথেষ্ট যে চিহ্নিত করা যথেষ্ট। Aristeia.com / পেপারস / ডিডিজে_জুল_আগ_2004_ রিভিউড.পিডিএফ দেখুন ।
i_am_jorf

0

আমি সমস্ত সমাধানগুলি পড়ে নিই না, সুতরাং এই কোডটি অপ্রয়োজনীয় হলে ক্ষমা করুন।

এটি আমার মতে সর্বাধিক থ্রেড নিরাপদ বাস্তবায়ন।

+(SingletonObject *) sharedManager
{
    static SingletonObject * sharedResourcesObj = nil;

    @synchronized(self)
    {
        if (!sharedResourcesObj)
        {
            sharedResourcesObj = [[SingletonObject alloc] init];
        }
    }

    return sharedResourcesObj;
}

-4

আমি সাধারণত বেন হফস্টেইনের উত্তরে (যা আমি উইকিপিডিয়া থেকেও বেরিয়ে এসেছি) প্রায় অনুরূপ কোড ব্যবহার করি। ক্রিস হ্যানসন তাঁর মন্তব্যে যে কারণে বলেছেন তার জন্য আমি এটি ব্যবহার করি।

যাইহোক, কখনও কখনও আমার একটি সিআইএলটিএনকে একটি এনআইবিতে রাখার প্রয়োজন হয় এবং সেই ক্ষেত্রে আমি নিম্নলিখিতগুলি ব্যবহার করি:

@implementation Singleton

static Singleton *singleton = nil;

- (id)init {
    static BOOL initialized = NO;
    if (!initialized) {
        self = [super init];
        singleton = self;
        initialized = YES;
    }
    return self;
}

+ (id)allocWithZone:(NSZone*)zone {
    @synchronized (self) {
        if (!singleton)
            singleton = [super allocWithZone:zone];     
    }
    return singleton;
}

+ (Singleton*)sharedSingleton {
    if (!singleton)
        [[Singleton alloc] init];
    return singleton;
}

@end

আমি পাঠ্যক্রমের -retain(ইত্যাদি) বাস্তবায়নটি ছেড়ে দিই , যদিও আবর্জনা সংগৃহীত পরিবেশে উপরের কোডটি আপনার প্রয়োজনীয়।


2
আপনার কোড থ্রেড-নিরাপদ নয়। এটি বরাদ্দ পদ্ধতিতে সিঙ্ক্রোনাইজড ব্যবহার করে, তবে আর ডি পদ্ধতিতে নয়। প্রাথমিক স্তরে পরীক্ষা করা থ্রেড-নিরাপদ নয়।
মক্কি

-5

গৃহীত উত্তরটি যদিও এটি সংকলন করে তা ভুল।

+ (MySingleton*)sharedInstance
{
    @synchronized(self)  <-------- self does not exist at class scope
    {
        if (sharedInstance == nil)
            sharedInstance = [[MySingleton alloc] init];
    }
    return sharedInstance;
}

প্রতি অ্যাপল ডকুমেন্টেশন:

... আপনি নিজের পরিবর্তে ক্লাস অবজেক্টটি ব্যবহার করে সম্পর্কিত ক্লাসের শ্রেণি পদ্ধতিগুলি সিঙ্ক্রোনাইজ করার জন্য একই ধরণের পদ্ধতি অবলম্বন করতে পারেন।

স্ব-কাজগুলি ব্যবহার করেও, এটি হওয়া উচিত নয় এবং এটি আমার কাছে অনুলিপি এবং অনুলিপি হিসাবে দেখায়। শ্রেণি কারখানার পদ্ধতির জন্য সঠিক প্রয়োগটি হ'ল:

+ (MySingleton*)getInstance
{
    @synchronized([MySingleton class]) 
    {
        if (sharedInstance == nil)
            sharedInstance = [[MySingleton alloc] init];
    }
    return sharedInstance;
}

6
স্ব অবশ্যই আছে এটা বর্গ সুযোগ বিদ্যমান। এটি ক্লাসের উদাহরণের পরিবর্তে শ্রেণিকে বোঝায়। ক্লাসগুলি (বেশিরভাগ) প্রথম শ্রেণীর অবজেক্ট।
schwa

আপনি কেন একটি পদ্ধতিতে @ সিংক্রোনাইনেজড রাখেন?
user4951

1
হিসাবে সচহা ইতিমধ্যে বললেন, self হয় একটি বর্গ পদ্ধতি বর্গ অবজেক্টের অভ্যন্তরে। এটি দেখানোর জন্য একটি স্নিপেটের জন্য আমার মন্তব্য দেখুন
jscs

selfউপস্থিত রয়েছে, তবে এটি শনাক্তকারী হিসাবে পাস হিসাবে ব্যবহার করা @synchronizedউদাহরণের পদ্ধতির অ্যাক্সেসকে সিঙ্ক্রোনাইজ করবে। @ ব্যবহারকারী 490696 হিসাবে উল্লেখ করা হয়েছে, এমন কিছু ক্ষেত্রে রয়েছে (সিঙ্গেলটনের মতো) যেখানে শ্রেণি অবজেক্ট ব্যবহার করা অধিকতর পছন্দসই। You can take a similar approach to synchronize the class methods of the associated class, using the class object instead of self. In the latter case, of course, only one thread at a time is allowed to execute a class method because there is only one class object that is shared by all callers.
ওবজে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.