не может получить доступ к изменяемому массиву в синглтоне - PullRequest
1 голос
/ 11 октября 2011

singleton.h

#import <Foundation/Foundation.h>
@interface CrestronControllerValues : NSObject {
NSString* ipAddress;
NSString* portNumber;
NSString* phoneAddress;
NSString* cameleonVersion;
NSString* systemName;
NSString* iPID;
NSString* systemFeedBackName;
NSString* dJoinConnectedFB;
NSString* dJoinLow;
NSString* dJoinHigh;
NSString* aJoinLow;
NSString* aJoinHigh;
NSString* sJoinLow;
NSString* sJoinHigh;
NSMutableArray *currentPhonebookEntriesTelepresence;
NSMutableArray *currentPhonebookEntriesVideoChat;
NSMutableArray *currentPhonebookEntriesAudioChat;

}
@property (nonatomic, retain)    NSString* ipAddress;

@property (nonatomic, retain)    NSString* portNumber;

@property (nonatomic, retain)    NSString* phoneAddress;

@property (nonatomic, retain)    NSString* cameleonVersion;

@property (nonatomic, retain)     NSMutableArray *currentPhonebookEntriesTelepresence;

@property (nonatomic, retain)     NSMutableArray *currentPhonebookEntriesVideoChat;

@property (nonatomic, retain)     NSMutableArray *currentPhonebookEntriesAudioChat;

@property (nonatomic, retain)    NSString* systemName;

@property (nonatomic, retain)    NSString* iPID;

@property (nonatomic, retain)    NSString* systemFeedBackName;

@property (nonatomic, retain)    NSString* dJoinConnectedFB;

@property (nonatomic, retain)    NSString* dJoinLow;

@property (nonatomic, retain)    NSString* dJoinHigh;

@property (nonatomic, retain)    NSString* aJoinLow;

@property (nonatomic, retain)    NSString* aJoinHigh;

@property (nonatomic, retain)    NSString* sJoinLow;

@property (nonatomic, retain)    NSString* sJoinHigh;

+ (id)sharedManager;
    @end

У меня есть мой синглтон.m:

        static CrestronControllerValues *sharedMyManager= nil;

    @implementation CrestronControllerValues
    @synthesize ipAddress, portNumber ,systemName, iPID, systemFeedBackName, dJoinConnectedFB, dJoinLow, dJoinHigh, aJoinLow, aJoinHigh, sJoinLow, sJoinHigh, cameleonVersion, currentPhonebookEntriesAudioChat, currentPhonebookEntriesTelepresence, currentPhonebookEntriesVideoChat, phoneAddress;


    +(CrestronControllerValues*)sharedManager
{
        @synchronized(self) {
    if(!sharedMyManager) {
        sharedMyManager = [CrestronControllerValues alloc];
        sharedMyManager = [sharedMyManager init];

    }
}
}

+(id)alloc
{
    @synchronized(self)
    {
        NSAssert(sharedMyManager == nil, @"Attempted to allocate a second instance of a singleton.");
        sharedMyManager = [super alloc];
        return sharedMyManager;
    }

    return nil;
}

    -(id)init {
        self = [super init];
        if (self != nil) {
            // initialize stuff here
        self.ipAddress = @"10.8.40.64";
self.portNumber = 41794;
self.systemName = @"";
self.iPID = 3;
self.cameleonVersion = nil;
self.currentPhonebookEntriesAudioChat = [[NSMutableArray alloc]initWithObjects:nil];  
self.currentPhonebookEntriesTelepresence = [[NSMutableArray alloc]initWithObjects:nil];
self.currentPhonebookEntriesVideoChat = [[NSMutableArray alloc]initWithObjects:nil];
self.phoneAddress = nil;
self.systemFeedBackName = @"";
self.dJoinConnectedFB = 5000;
self.dJoinLow = 1;
self.dJoinHigh = 1000;
self.aJoinLow = 1;
self.aJoinHigh = 1000;
self.sJoinLow = 1;
self.sJoinHigh = 1000;

        }
        return self; 
    }
        return self; 
    }

    -(void)setPhoneAddress:(NSString *)phoneaddress
    {
        @synchronized(self) {
            if (phoneAddress != phoneaddress) 
            {
                [phoneAddress release];
                phoneAddress = [phoneaddress retain];
            }
        }
    }
    -(NSString*)getPhoneAddress
    {
        return phoneAddress;
    }
    -(void)setCurrentPhonebookEntriesAudioChat:(NSMutableArray *)entries
    {
        @synchronized(self) {
            if (currentPhonebookEntriesAudioChat != entries) 
            {
                [currentPhonebookEntriesAudioChat release];
                currentPhonebookEntriesAudioChat = [entries retain];
            }
        }
    }
    -(NSMutableArray*)getCurrentPhonebookEntriesAudioChat
    {
        return currentPhonebookEntriesAudioChat;
    }
    -(void)setCurrentPhonebookEntriesTelepresence:(NSMutableArray *)entries
    {
        @synchronized(self) {
            if (currentPhonebookEntriesTelepresence != entries) 
            {
                [currentPhonebookEntriesTelepresence release];
                currentPhonebookEntriesTelepresence = [entries retain];
            }
        }
    }
    -(NSMutableArray*)getCurrentPhonebookEntriesTelepresence
    {
        return currentPhonebookEntriesTelepresence;
    }
    -(void)setCurrentPhonebookEntriesVideoChat:(NSMutableArray *)entries
    {
        @synchronized(self) {
            if (currentPhonebookEntriesVideoChat != entries) 
            {
                [currentPhonebookEntriesVideoChat release];
                currentPhonebookEntriesVideoChat = [entries retain];
            }
        }
    }
    -(NSMutableArray*)getCurrentPhonebookEntriesVideoChatLocal
    {
        return currentPhonebookEntriesVideoChat;
    }
    -(void)setCameleonVersion:(NSString *)cameleonversion
    {
        cameleonVersion = cameleonversion;
    }
    -(NSString*)getCameleonVersion
    {
        return cameleonVersion;
    }
    -(void)setIPaddress:(NSString *)ipaddress
    {
        ipAddress = ipaddress;
    }
    -(NSString*)getIPaddress
    {
        return ipAddress;
    }
    -(void)setPortNumber:(NSString *)portnumber
    {
        portNumber = portnumber;
    }
    -(NSString*)getPortNumber
    {
        return portNumber;
    }
    -(void)setSystemName:(NSString *)systemname
    {
        systemName = systemname;
    }
    -(NSString*)getSystemName
    {
        return systemName;
    }

    -(void)setIPID:(NSString *)ipid 
    {
        iPID=ipid;
    }
    -(NSString*)getIpid
    {
        return iPID;
    }

    -(void)setSystemFeedBackName:(NSString *)systemfeedbackname
    {
        systemFeedBackName=systemfeedbackname;
    }
    -(NSString*)getSystemFeedBackName
    {
        return systemFeedBackName;
    }

    -(void)setDJoinConnectedFB:(NSString *)djoinconnectedfb
    {
        dJoinConnectedFB = djoinconnectedfb;
    }
    -(NSString*)getDJoinConnectedFB
    {
        return dJoinConnectedFB;
    }

    -(void)setDJoinLow:(NSString *)djoinlow
    {
        dJoinLow=djoinlow;
    }
    -(NSString*)getDJoinLow
    {
        return dJoinLow;
    }

    -(void)setDJoinHigh:(NSString *)djoinhigh
    {
        dJoinHigh = djoinhigh;
    }
    -(NSString*)getDJoinHigh
    {
        return dJoinHigh;
    }

    -(void)setAJoinLow:(NSString *)ajoinlow
    {
        aJoinLow = ajoinlow;
    }
    -(NSString*)getAJoinLow
    {
        return aJoinLow;
    }

    -(void)setAJoinHigh:(NSString *)ajoinhigh
    {
        aJoinHigh = ajoinhigh;
    }
    -(NSString*)getAJoinHigh
    {
        return aJoinHigh;
    }

    -(void)setSJoinLow:(NSString *)sjoinlow
    {
        sJoinLow = sjoinlow;
    }
    -(NSString*)getSJoinLow
    {
        return sJoinLow;
    }

    -(void)setSJoinHigh:(NSString *)sjoinhigh
    {
        sJoinHigh = sjoinhigh;
    }
    -(NSString*)getSJoinHigh
    {
        return sJoinHigh;
    }

    - (void)dealloc
    {
        [self.ipAddress release];
        [self.iPID release];
        [self.portNumber release];
        [self.currentPhonebookEntriesVideoChat release];
        [self.currentPhonebookEntriesTelepresence release];
        [self.currentPhonebookEntriesAudioChat release];
        [self.aJoinHigh release];
        [self.aJoinLow release];
        [self.cameleonVersion release];
        [self.sJoinHigh release];
        [self.sJoinLow release];
        [self.dJoinHigh release];
        [self.dJoinLow release];
        [self.dJoinConnectedFB release];
        [super dealloc];
    }

    @end

и затем я использую его в 3 классах в одном я устанавливаю значения: если я читаю значения из CCV (sharedobject), я получаю правильные значения. но это в том же классе, как они установлены с

CCV = [CrestronControllerValues sharedManager];
CCV.currentPhonebookEntriesAudioChat = currentPhonebookEntriesAudioChat;

и еще я читаю значения: (показывают / читают как ноль)

switch (viewOptions) {
    case 1:
        [self setTableArray:CCV.currentPhonebookEntriesVideoChat];
        break;
    case 2:
        [self setTableArray:CCV.currentPhonebookEntriesVideoChat];
        break;
    case 3:
        [self setTableArray:CCV.currentPhonebookEntriesTelepresence];
        break;
    case 4:
        [self setTableArray:CCV.currentPhonebookEntriesAudioChat];
        break;
    default:
        [self setTableArray:CCV.currentPhonebookEntriesVideoChat];
        break;
}

но кроме того класса, в котором я на самом деле устанавливаю значения, я не получаю заполненный массив при доступе к нему из другого класса я сделал NSLOG (@ "% @", CCV) и из того, что я вижу, все три класса имеют один и тот же указатель, поэтому кажется, что общий экземпляр работает

Ответы [ 4 ]

2 голосов
/ 12 октября 2011

Вот более простой шаблон синглтона, меньше кода больше:

@implementation MySingleton
static MySingleton* _sharedMySingleton = nil;

+(MySingleton*)sharedMySingleton
{
    @synchronized([MySingleton class])
    {
        if (!_sharedMySingleton)
            _sharedSingleton = [[MySingleton alloc] init];
    }

    return _sharedMySingleton;
}
1 голос
/ 13 октября 2011

так что в итоге все, что я могу сделать, это извиниться. Ни у кого из вас не было кода, который вам понадобился бы, чтобы увидеть, что происходит.
вот сохраняемый массив (выше было сокращено (плохая идея))

            if ([phonebookEntriesAudioChat count] >=8) {                

                [CCV setCurrentPhonebookEntriesAudioChat:phonebookEntriesAudioChat];
                [phonebookEntriesAudioChat removeAllObjects];

            }

В основном я пытался добавить элемент в массив из возврата сокета. получение одного адреса до 8 для каждого возврата / сообщения. поэтому я заполнил временный массив (phonebookEntriesAudioChat) и добавил один к нему для каждого сообщения, и как только он достиг 8, сохранил его в моем синглтоне (CCV). но кое-как (и я все еще пытаюсь это выяснить) он получит значение 8, будет сохранен, временный массив очищен, а затем сохранен массив (пустой) в синглтоне.

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

1 голос
/ 11 октября 2011

Рассмотрим:

sharedMyManager = [[super allocWithZone:NULL] init];

Перепишите его как:

id x = [super allocWithZone:NULL];
id y = [x init];
sharedMyManager = y;

Когда выполняется init, присвоение sharedMyManager еще не было оценено.Таким образом, sharedMyManager - это nil, и все ваши назначения не используются в вашем методе init.

В вашем методе init вы должны всегда ссылаться на ваш экземплярпеременные через self;либо непосредственно присваивая им (что на самом деле является ссылкой на себя), либо напрямую используя методы установки (т. е. self.foo = 442;).

(Это то, что @CocoaFu сказал, но пояснил)

Если присмотреться к коду, то с ним куча проблем.

  • NSString свойства должны быть copy, а не retain.

  • вы пропускаете все изменяемые массивы currentPhonebookEntries*.

  • Методы получения не должны иметь префикс get*

  • нет необходимости реализовывать какой-либо из этих методов получения / установки при использовании @synthesize (и вы фактически создаете два метода получения для каждого; один с префиксом get и один без него).

  • метод dealloc должен либо напрямую освобождать переменные экземпляра, либо устанавливать для свойств nil;[self.ivar release] не рекомендуется.

Код, который я показал выше, является просто иллюстративным.Если ваш init все еще назначает через sharedMyManager, вы не устранили проблему.

1 голос
/ 11 октября 2011

sharedMyManager не был установлен во время инициализации иваров.

В инициализации лучше всего устанавливать ивары напрямую, то есть не использовать сеттеры, такие как созданные @synthesize, класс не полностью установлен, поэтому вызов методов для него не очень хорошая идея.

Синглтон - это просто класс, как и любой другой класс, с одним исключением, только один.Кроме того, все дополнительные методы, гарантирующие использование синглтона, - это на самом деле просто шум, который лучше всего не показывать, но это вопрос вкуса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...