Как создать синглтон-класс в задаче C - PullRequest
38 голосов
/ 21 марта 2011

Как я могу создать одноэлементный класс в Objective C?

Ответы [ 14 ]

53 голосов
/ 09 апреля 2012

Хорошо, appDev, вы, вероятно, найдете несколько различных способов сделать это в Интернете.Однако, для разработки приложений для iOS, я думаю, что наиболее удобный способ - это сделать следующее:

  • Напишите ваши методы для получения одноэлементного объекта.(Рекомендация: для этого используйте dispatch_once thread и GCD).

  • Оберните ваши методы в макрос и добавьте их в файл $Project$-Prefix.pch.

  • Вызывайте однострочный макрос всякий раз, когда вынужен одноэлементный объект для класса.

Пример:

CommonMacros.h :

#define SINGLETON_FOR_CLASS(classname)
+ (id) shared##classname {
    static dispatch_once_t pred = 0;
    static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

YourProject-Prefix.pch:

...
#import "CommonMacros.h"
...

YourSingletonClass.m:

...
SINGLETON_FOR_CLASS(YourSingletonClass)
...
26 голосов
/ 21 марта 2011

Проверьте эту ссылку для исходного источника - http://getsetgames.com/2009/08/30/the-objective-c-singleton/

@implementation MySingleton
static MySingleton *_sharedMySingleton = nil;

+(MySingleton *)sharedMySingleton {
    @synchronized([MySingleton class]) {
        if (!_sharedMySingleton)
          _sharedMySingleton = [[self alloc] init];
        return _sharedMySingleton;
    }
    return nil;
}
21 голосов
/ 05 декабря 2013

Я действительно думаю, что именно так мы можем по-настоящему добиться одноэлементного поведения:

@interface SampleSingletonClass : NSObject

+ sharedSampleSingletonClass;

@end


@implementation SampleSingletonClass
static SampleSingletonClass *singletonObject = nil;

+ (id) sharedSampleSingletonClass
{
    if (! singletonObject) {

        singletonObject = [[SampleSingletonClass alloc] init];
    }
    return singletonObject;
}

- (id)init
{
    if (! singletonObject) {

        singletonObject = [super init];
    // Uncomment the following line to see how many times is the init method of the class is called
    // NSLog(@"%s", __PRETTY_FUNCTION__);
    }
    return singletonObject;
}

@end

Здесь, даже если один вызывает метод init вместо намеченного + (id) SampleSingletonClass;Метод фактический объект формируется только один раз в течение жизненного цикла приложения.

12 голосов
/ 06 марта 2013

Это мой личный любимый способ сделать это:

+ (instancetype)sharedObject {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
11 голосов
/ 16 октября 2013

Вы можете реализовать одноэлементный класс в Objective-C.

+ (id)sharedManager {
    static MyManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (id)init {
  if (self = [super init]) {
      someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
  }
  return self;
}

http://www.galloway.me.uk/tutorials/singleton-classes/

6 голосов
/ 13 января 2016

От: http://www.galloway.me.uk/tutorials/singleton-classes/

Одиночки в Objective-C

Один из моих наиболее часто используемых шаблонов проектирования при разработке для iOS - этосинглтонЭто чрезвычайно эффективный способ обмена данными между различными частями кода без необходимости передавать данные вручную.

Фон

Синглтон-классы - это важная концепция, которую нужно понимать, потому чтоони демонстрируют чрезвычайно полезную модель дизайна.Эта идея используется в iPhone SDK, например, в UIApplication есть метод sharedApplication, который при вызове из любого места возвращает экземпляр UIApplication, относящийся к текущему приложению.

Как реализовать

Singletone.h

#import <foundation/Foundation.h>

@interface Singleton : NSObject {
}

 @property (nonatomic, retain) NSString *someProperty;

  + (id)sharedManager;

 @end

Singleton.m

#import "Singleton.h"

@implementation Singleton

@synthesize someProperty;

#pragma mark Singleton Methods

 + (id)sharedManager {
   static Singleton *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    sharedMyManager = [[self alloc] init];
  });
  return sharedMyManager;
 }

 - (id)init {
  if (self = [super init]) {
     someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
  }
return self;
}

@end

Что это делает, это определяетстатическая переменная (но только глобальная для этого модуля перевода)) с именем sharedMyManager , которая затем инициализируется один раз и только один раз в sharedManager .Мы гарантируем, что он будет создан только один раз, используя метод dispatch_once из Grand Central Dispatch (GCD) .Это поточно-ориентированный и полностью обрабатывается операционной системой для вас, так что вам не нужно об этом беспокоиться.

4 голосов
/ 08 июля 2014

Попробуйте это

Класс Singhton .h file

#import <Foundation/Foundation.h>

@interface GlobleDirector : NSObject
+(GlobleDirector*)shareManager;
@end

Файл класса Singalton .m

#import "GlobleDirector.h"

@implementation GlobleDirector


+(GlobleDirector*)shareManager{

static GlobleDirector *sharedInstance=nil;
static dispatch_once_t  oncePredecate;

dispatch_once(&oncePredecate,^{
    sharedInstance=[[GlobleDirector alloc] init];

 });
return sharedInstance;
}



@end
1 голос
/ 20 июня 2016
#import <Foundation/Foundation.h>

@interface singt : NSObject  

+ (id)sharedManager;

@end


#import "singt.h"

@implementation singt


+ (id)sharedManager 

{

    static singt *sharedMyManager = nil;
     static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];


    });

    return sharedMyManager;

}
1 голос
/ 28 мая 2014

Я знаю, что предполагается, что посетители знают, что такое синглтон, но чтобы помочь тем, кто не знает, я предлагаю этот простой небольшой пример с общими данными.

Объект используется для экземпляров классов общих данныхили экземпляры класса (классов).

@interface SharedData : NSObject {
    id data;
}
- (void)setData:(id)data_;
- (id)data;
@end

@implementation SharedData
//>> singleton
static SharedData *sharedData=nil;
+ (SharedData*)sharedData {
    @synchronized (self) {
        if (sharedData==nil) sharedData=[[self alloc]init];
    }
    return sharedData;
}
//<<
- (void)setData:(id)data_ {
    data=data_;
}
- (id)data {
    return data;
}
@end

... Первый вызов (+ sharedData) создает экземпляр объекта, основываясь на его ссылке на статическую переменную (общая локаль), которую он возвращает как экземпляр ref.Следующий вызов возвращает только ссылку на статическую переменную.

Данные могут быть установлены / получены в любое время с помощью встроенного средства доступа.

Это приводит к относительному упрощению совместного использования объекта, но это возможнообрабатывать "вручную" путем совместного использования ссылок.

@ synchronized просто необходим для многопоточности.Для простого совместного использования экземпляров классов это не требуется.

Расширенное объяснение здесь: http://www.galloway.me.uk/tutorials/singleton-classes/

1 голос
/ 04 июня 2013
    static DBHandler* sDBHandler = nil;

- (id)init
{
    self = [super init];
    if (self) {
        [self checkAndCreateDatabase];
    }
    return self;
}

+(id)sharedDBHandler
{
    @synchronized (self) {
        if (sDBHandler == nil) {
            sDBHandler = [self new];
        }
    }
    return sDBHandler;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...