开发者

cannot access mutable array in singleton

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

i have my singleton.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];
                currentPhone开发者_开发百科bookEntriesTelepresence = [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

and then i use it in 3 classes total in one i set values: if i read values from the CCV (sharedobject) i get the correct values. but this is in the same class as they are set from

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

and another i read the values: (these show/read as nil)

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;
}

but besides the class that i actually set the values in i do not get the filled array when i access it from another class i have done NSLOG(@"%@", CCV) and from what i can see all three classes have the same pointer so the shared instance seems to be working


Here is a simplier singleton pattern, less code is more:

@implementation MySingleton
static MySingleton* _sharedMySingleton = nil;

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

    return _sharedMySingleton;
}


sharedMyManager has not been set at the time you are initializing the ivars.

In a init it is best practice to set the ivars directly, that is do not use setters such as created by @synthesize, the class is not completely established so calling methods on it is not a great idea.

A singleton is just a class like any other class with one exception, there is only one. Also all the extra methods to guarantee a singleton are really just noise that is best not present--but that is a matter of taste.


Consider:

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

Rewrite it as:

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

When init is executed, the assignment to sharedMyManager hasn't been evaluated yet. Thus, sharedMyManager is nil and all your assignments are no-ops in your init method.

In your init method, you should always refer to your instance variables through self; either by directly assignment to them (which is a reference to self, really) or using the setter methods directly (i.e. self.foo = 442;).

(This is what @CocoaFu said, but clarified)


Looking at the code a little more closely, there are a ton of problems with it.

  • NSString properties should be copy, not retain.

  • you are leaking all of the currentPhonebookEntries* mutable arrays.

  • Getter methods should not have the prefix get*

  • there is no need to implement any of those getter/setter methods when using @synthesize (and you are actually creating two getter methods for each; one with and one without the get prefix).

  • the dealloc method should either directly release the instance variables or it should set the properties to nil; the [self.ivar release] is discouraged.

The code I showed above is merely illustrative. If your init still assigns through sharedMyManager, you didn't fix the problem.


so in the end all i can do is apologize. none of you had the code that you would have needed to see what was going on.
here is the array being saved (aboved was abridged (bad idea))

            if ([phonebookEntriesAudioChat count] >=8) {                

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

            }

basically i was tring to add an item to the array from a socket return. getting one address up to 8 for each return/message. so i populated a temporary array (phonebookEntriesAudioChat) and added one to it for each message and once it got to 8 saved it to my singleton (CCV). but some how (and im still trying to figure this out) it would get to 8, be saved, temporary array cleared, then resaved the array (an empty one) to the singleton.

thanks for all the help and direction, i know i dont get points for my own answer if one of you wants some easy points just re answer with a simliar description as this and ill give u the check. otherwise im just going to vote up ur comments and mark this as the answer in a day or two.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜