objective c - কিভাবে আমি একটি উদ্দেশ্য-সি সিঙ্গল্ট বাস্তবায়ন করব যা এআরসি এর সাথে সামঞ্জস্যপূর্ণ?




objective-c ios (7)

আপনি প্রয়োজন হিসাবে অন্যান্য উদাহরণ তৈরি করতে চান। এই কাজ:

+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

অন্যথায়, আপনাকে এটি করা উচিত:

+ (id)allocWithZone:(NSZone *)zone
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

এক্সকোড 4.2 এ স্বয়ংক্রিয় রেফারেন্স কাউন্টিং (এআরসি) ব্যবহার করার সময় আমি কীভাবে একক্টন ক্লাসটিকে রূপান্তর করব (বা তৈরি করব) যা কম্পাইল এবং সঠিকভাবে আচরণ করে?


এই উত্তর পড়ুন এবং তারপর যান এবং অন্যান্য উত্তর পড়তে।

একটানা বোঝার দরকার নেই যে সিঙ্গলটনের অর্থ কী এবং তার প্রয়োজনীয়তা কী, যদি আপনি এটি বুঝতে না পান তবে সমাধানটি বুঝতে পারছেন না!

সফলভাবে সিঙ্গলটন তৈরি করতে আপনাকে নিম্নলিখিত 3 টি করতে সক্ষম হবেন:

  • যদি কোনও জাতি শর্ত থাকে , তবে একই সময়ে আপনার ভাগ করা ইনস্ট্যান্সের একাধিক দৃষ্টান্ত আমরা তৈরি করতে পারি না!
  • মনে রাখবেন এবং একাধিক invocations মধ্যে মান রাখা।
  • এটি শুধুমাত্র একবার তৈরি করুন। এন্ট্রি পয়েন্ট নিয়ন্ত্রণ করে।

dispatch_once_t আপনাকে শুধুমাত্র একবারের ব্লকটিকে একবার প্রেরণ করার অনুমতি দিয়ে একটি রেস অবস্থায় সমাধান করতে সহায়তা করে।

Static আপনাকে যেকোন সংখ্যক আমন্ত্রণগুলিতে তার মান "মনে রাখতে" সহায়তা করে। এটা কিভাবে মনে আছে? এটি কোনও নতুন ইনস্ট্যান্সকে আপনার ভাগ করা ইনস্ট্যান্সের সঠিক নামের সাথে পুনরায় তৈরি করার অনুমতি দেয় না, এটি মূলত তৈরি করা হয়েছে এমনটি দিয়ে কাজ করে।

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

কোকো নিজেই আসা সবচেয়ে সাধারণ সিস্টেম সিঙ্গলনগুলির মধ্যে কয়েকটি হল:

  • [UIApplication sharedApplication]
  • [NSUserDefaults standardUserDefaults]
  • [NSFileManager defaultManager]
  • [NSBundle mainBundle]
  • [NSOperations mainQueue]
  • [NSNotificationCenter defaultCenter]

কেন্দ্রীভূত প্রভাব আছে যে মূলত কিছু যে একটি সিঙ্গলটন নকশা প্যাটার্ন কিছু ধরণের অনুসরণ করা প্রয়োজন।


গৃহীত উত্তরগুলির সাথে দুটি সমস্যা রয়েছে যা আপনার উদ্দেশ্যের জন্য প্রাসঙ্গিক হতে পারে বা নাও হতে পারে।

  1. যদি init পদ্ধতি থেকে, কোনভাবেই ভাগ করা ইনস্ট্যান্স পদ্ধতিটি আবার বলা হয় (উদাহরণস্বরূপ যেহেতু অন্য বস্তুগুলি সিঙ্গল্ট ব্যবহার করে সেখানে তৈরি হয়) এটি স্ট্যাক ওভারফ্লো সৃষ্টি করবে।
  2. শ্রেণীর আধিপত্যের জন্য কেবলমাত্র একক সিঙ্গলন (অর্থাত্: প্রথম শ্রেণিতে যা শ্রেণীবদ্ধ পদ্ধতিতে বলা হয়েছিল) প্রথম শ্রেণির পরিবর্তে এককন্টন প্রতি কংক্রিট শ্রেণির পরিবর্তে।

নিম্নলিখিত কোডটি এই দুটি সমস্যার যত্ন নেয়:

+ (instancetype)sharedInstance {
    static id mutex = nil;
    static NSMutableDictionary *instances = nil;

    //Initialize the mutex and instances dictionary in a thread safe manner
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mutex = [NSObject new];
        instances = [NSMutableDictionary new];
    });

    id instance = nil;

    //Now synchronize on the mutex
    //Note: do not synchronize on self, since self may differ depending on which class this method is called on
    @synchronized(mutex) {
        id <NSCopying> key = (id <NSCopying>)self;
        instance = instances[key];
        if (instance == nil) {
            //Break allocation and initialization into two statements to prevent a , if init somehow calls the sharedInstance method
            id allocatedInstance = [self alloc];

            //Store the instance into the dictionary, one per concrete class (class acts as key for the dictionary)
            //Do this right after allocation to avoid the  problem
            if (allocatedInstance != nil) {
                instances[key] = allocatedInstance;
            }
            instance = [allocatedInstance init];

            //Following code may be overly cautious
            if (instance != allocatedInstance) {
                //Somehow the init method did not return the same instance as the alloc method
                if (instance == nil) {
                    //If init returns nil: immediately remove the instance again
                    [instances removeObjectForKey:key];
                } else {
                    //Else: put the instance in the dictionary instead of the allocatedInstance
                    instances[key] = instance;
                }
            }
        }
    }
    return instance;
}

ঠিক একই ভাবে আপনি (ইতিমধ্যে) এটি করা হয়েছে:

+ (instancetype)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

যদি আপনি দ্রুত একক্টন তৈরি করতে হবে,

class var sharedInstance: MyClass {
    struct Singleton {
        static let instance = MyClass()
    }
    return Singleton.instance
}

অথবা

struct Singleton {
    static let sharedInstance = MyClass()
}

class var sharedInstance: MyClass {
    return Singleton.sharedInstance
}

আপনি এই ভাবে ব্যবহার করতে পারেন

let sharedClass = LibraryAPI.sharedInstance

সিঙ্গলটন ক্লাস: যেকোনো ক্ষেত্রে বা কোনও উপায়ে ক্লাসের একাধিক বস্তু তৈরি করতে পারে না।

+ (instancetype)sharedInstance
{
    static ClassName *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[ClassName alloc] init];
        // Perform other initialisation...
    });
    return sharedInstance;
}
//    You need need to override init method as well, because developer can call [[MyClass alloc]init] method also. that time also we have to return sharedInstance only. 

-(MyClass)init
{
   return [ClassName sharedInstance];
}

#import <Foundation/Foundation.h>

@interface SingleTon : NSObject

@property (nonatomic,strong) NSString *name;
+(SingleTon *) theSingleTon;

@end

#import "SingleTon.h"
@implementation SingleTon

+(SingleTon *) theSingleTon{
    static SingleTon *theSingleTon = nil;

    if (!theSingleTon) {

        theSingleTon = [[super allocWithZone:nil] init
                     ];
    }
    return theSingleTon;
}

+(id)allocWithZone:(struct _NSZone *)zone{

    return [self theSingleTon];
}

-(id)init{

    self = [super init];
    if (self) {
        // Set Variables
        _name = @"Kiran";
    }

    return self;
}

@end

উপরের কোড আশা করি এটা সাহায্য করবে।






automatic-ref-counting