Get NSMutableDictionary from Singleton? - objective-c

I created a singleton class in order to share an object inside my program. Here's the code:
SelectedRow.h
#import <Foundation/Foundation.h>
#import "TableEntry.h"
#interface SelectedRow : NSObject {
TableEntry *rowValue;
}
#property (nonatomic, retain) TableEntry *rowValue;
+ (id)sharedManager;
- (void)setVariable:(TableEntry*)value;
#end
and SelectedRow.m
#import "SelectedRow.h"
#import "TableEntry.h"
#implementation SelectedRow
#synthesize rowValue;
+ (id)sharedManager {
static SelectedRow *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
rowValue = [[TableEntry alloc] init];
}
return self;
}
- (void)setVariable:(TableEntry*)value {
rowValue = value;
}
#end
while TableEntry.h
#import <Foundation/Foundation.h>
#interface TableEntry : NSObject {
#private
NSString *videoId;
NSString *videoCategory;
NSString *videoTitle;
NSString *videoDescription;
NSDate *videoDate;
NSMutableArray *videoRelatedVideos;
NSDictionary *videoAdditionalInformation;
NSString *videoAccessControl;
NSArray *videoFields;
NSMutableDictionary *days;
NSMutableDictionary *views;
NSMutableDictionary *watchtime;
NSMutableDictionary *subscribers;
NSMutableDictionary *shares;
}
#property (copy) NSString *videoId;
#property (copy) NSString *videoCategory;
#property (copy) NSString *videoTitle;
#property (copy) NSString *videoDescription;
#property (copy) NSMutableArray *videoRelatedVideos;
#property (copy) NSDictionary *videoAdditionalInformation;
#property (copy) NSArray *videoFields;
#property (copy) NSString *videoAccessControl;
#property (copy) NSDate *videoDate;
#property (copy) NSMutableDictionary *days;
#property (copy) NSMutableDictionary *views;
#property (copy) NSMutableDictionary *subscribers;
#property (copy) NSMutableDictionary *shares;
#property (copy) NSMutableDictionary *watchtime;
- (id)setId:(NSString*)Id setCategory:(NSString*)Category setDate:(NSDate*)date setTitle:(NSString*)title setDescription:(NSString*)description setRelatedVideos:(NSMutableArray*)relatedVideos setAdditionalInformation:(NSDictionary*)additionalInformation setAccessControl:(NSString*)accessControl setFields:(NSArray*)fields setDays:(NSMutableDictionary*)days setViews:(NSMutableDictionary*)views setSubscribers:(NSMutableDictionary*)subscribers setShares:(NSMutableDictionary*)shares setWatchtime:(NSMutableDictionary*)watchtime;
- (NSString*)extractId;
- (NSString*)extractCategory;
- (NSString*)extractTitle;
- (NSString*)extractDescription;
- (NSMutableArray*)extractRelatedVideos;
- (NSDictionary*)extractAdditionalInformationVideos;
- (NSDictionary*)extractAccessControlVideos;
- (NSArray*)extractFields;
- (NSMutableDictionary*)extractDays;
- (NSMutableDictionary*)extractViews;
- (NSMutableDictionary*)extractSubscribers;
- (NSMutableDictionary*)extractShares;
- (NSMutableDictionary*)extractWatchtime;
#end
and TableEntry.m
- (id)init {
self = [super init];
if (self) {
videoId = #"9bZkp7q19f0";
videoCategory = #"Music";
videoTitle = #"Demo Title";
videoDescription = #"Demo description";
videoDate = [NSDate date];
videoAdditionalInformation = [NSDictionary alloc];
videoRelatedVideos = [NSMutableArray alloc];
videoAccessControl = #"demo accesControl";
videoFields = [NSArray alloc];
days = [NSMutableDictionary alloc];
views = [NSMutableDictionary alloc];
shares = [NSMutableDictionary alloc];
subscribers = [NSMutableDictionary alloc];
watchtime = [NSMutableDictionary alloc];
}
return self;
}
- (id)setId:(NSString*)Id setCategory:(NSString*)Category setDate:(NSDate*)date setTitle:(NSString*)title setDescription:(NSString*)description setRelatedVideos:(NSMutableArray*)relatedVideos setAdditionalInformation:(NSDictionary*)additionalInformation setAccessControl:(NSString*)accessControl setFields:(NSArray*)fields setDays:(NSMutableDictionary*)Days setViews:(NSMutableDictionary*)Views setSubscribers:(NSMutableDictionary*)Subscribers setShares:(NSMutableDictionary*)Shares setWatchtime:(NSMutableDictionary*)Watchtime {
videoId = Id;
videoCategory = Category;
videoDate = date;
videoTitle = title;
videoDescription = description;
videoRelatedVideos = relatedVideos;
videoAccessControl = accessControl;
videoAdditionalInformation = additionalInformation;
videoFields = fields;
days = Days;
views = Views;
subscribers = Subscribers;
watchtime = Watchtime;
shares = Shares;
return self;
}
- (NSString*)extractId {
return self.videoId;
}
- (NSString*)extractCategory{
return self.videoCategory;
}
- (NSString*)extractTitle{
return self.videoTitle;
}
- (NSString*)extractDescription{
return self.videoDescription;
}
- (NSMutableArray*)extractRelatedVideos{
return self.videoRelatedVideos;
}
- (NSString*)extractAccessControlVideos{
return self.videoAccessControl;
}
- (NSDictionary*)extractAdditionalInformationVideos{
return self.videoAdditionalInformation;
}
- (NSArray*)extractFields{
return self.videoFields;
}
- (NSMutableDictionary*)extractDays{
return self.days;
}
- (NSMutableDictionary*)extractSubscribers{
return self.subscribers;
}
- (NSMutableDictionary*)extractWatchtime{
return self.watchtime;
}
- (NSMutableDictionary*)extractShares{
return self.shares;
}
- (NSMutableDictionary*)extractViews{
return self.views;
}
#end
I can extract any values from the singleton with:
SelectedRow *selectedRow = [SelectedRow sharedManager];
NSString *videoID = [selectedRow.rowValue extractId];
the problem arises with any NSMutableDictionary. If I try:
SelectedRow *selectedRow = [SelectedRow sharedManager];
NSMutableDictionary *days = [selectedRow.rowValue extractDays];
or with any other NSMutableDictionary I get this error:
[NSMutableDictionary count]: method sent to an uninitialized mutable dictionary object
what I'm I doing wrong? Thanks

The [NSMutableDictionary alloc] call allocates the space for NSMutableDictionary, but it does not initialize it.
Replace it with [NSMutableDictionary dictionary] to fix the problem. Same goes for your NSArray and NSMutableArray objects (replace them with [NSMutable array] and [NSMutableArray array]).
The videoAdditionalInformation of type NSDictionary should be initialized to nil, though, because NSDictionary objects are immutable. If you are planning to set it to some dictionary later on, you might as well keep it nil on initialization.
In addition, you should reconsider the use of copy: it makes sense for NSString objects, but it hardly makes sense on NSMutableDictionary objects.

Related

Is there any way to emulate user's input in XCTest function?

I have method which expects user's input
#implementation TeamFormation
- (void)run {
NSFileHandle *kbd = [NSFileHandle fileHandleWithStandardInput];
NSData *inputData = [kbd availableData];
NSString *option = [[[NSString alloc] initWithData:inputData
encoding:NSUTF8StringEncoding] substringToIndex:1];
NSLog(#"%#",option);
}
#end
Then I would like to cover this method by a test case
#interface TeamFormationTests : XCTestCase
#end
#implementation TeamFormationTests
- (void)testTeamFormation {
TeamFormation *teamFormation = [TeamFormation new];
[teamFormation run];
// emulate user's input here
}
#end
So, how to emulate user's input in test case function?
You have many options how to achieve this. Two obvious below.
Change run to accept an argument
- (void)run to - (void)runWithFileHandle:(NSFileHandle *)handle
your app code can pass stdin filehandle
your test code can pass handle to a file with desired input
Mock it with protocol
Create DataProvider protocol:
#protocol DataProvider
#property(readonly, copy) NSData *availableData;
#end
Make NSFileHandle to conform to this protocol:
#interface NSFileHandle (AvailableDataProvider) <DataProvider>
#end
Store an object implementing this protocol on TeamFormation:
#interface TeamFormation : NSObject
#property (nonatomic, nonnull, strong) id<DataProvider> dataProvider;
- (NSString *)run;
#end
By default, use stdin file handle:
#implementation TeamFormation
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataProvider = [NSFileHandle fileHandleWithStandardInput];
return self;
}
- (NSString *)run {
NSData *inputData = [self.dataProvider availableData];
return [[[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding] substringToIndex:1];
}
#end
Create TestDataProvider in your test:
#interface TestDataProvider: NSObject<DataProvider>
#property (nonatomic, strong, nonnull) NSData *dataToProvide;
#end
#implementation TestDataProvider
- (instancetype)init {
if ((self = [super init]) == nil) {
return nil;
}
_dataToProvide = [NSData new];
return self;
}
- (NSData *)availableData {
return _dataToProvide;
}
#end
And use it in TestFormationTests:
#implementation TeamFormationTests
- (void)testFormationRun {
TestDataProvider *dataProvider = [TestDataProvider new];
TeamFormation *formation = [TeamFormation new];
formation.dataProvider = dataProvider;
XCTAssertThrows([formation run]);
dataProvider.dataToProvide = [#"foo" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], #"f");
dataProvider.dataToProvide = [#"bar" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertEqualObjects([formation run], #"b");
}
#end

NSUserDefaults returning nil for some strings in array

I have a custom Object "Woman". I am trying to store the following values in it and save it in a mutable array using NSUserDefaults. The code I use for such is below. I also am using NSCoding in the object.
if (women ==nil) {
women =[[NSMutableArray alloc] init];
}
NSString *string =[NSString stringWithFormat:#"%f", interval];
//store to woman object
Woman* woman = [[Woman alloc] initWithFull:nameOfGirl withdate2:perfectdate withintervalLength:string withperiodLength:[NSString stringWithFormat:#"432000"] withpmsLength:[NSString stringWithFormat:#"432000"]];
[women addObject:woman];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:women] forKey:#"women"];
I use this code to retrieve it:
//pull women from archive
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults valueForKey:#"women"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
women = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
women = [[NSMutableArray alloc] init];
}
The result is in the screenshot. What is interesting to me is that the first string makes it but the other ones don't. :
EDIT: Here is my custom class.
.h:
#import <Foundation/Foundation.h>
#interface Woman : NSObject <NSCoding>
#property (nonatomic,strong) NSString *girlname;
#property (nonatomic,strong) NSDate *date2;
#property (nonatomic,strong) NSString *intervalLength;
#property (nonatomic,strong) NSString *periodLength;
#property (nonatomic, strong) NSString *pmsLength;
- (id)initWithFull:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength;
- (id)initWithNoInterval:(NSString *)girlname withdate2:(NSDate *)date2 withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength;
- (id)initWithIntervalnoPMSPeriod:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength;
- (void) encodeWithCoder:(NSCoder*)encode;
- (id) initWithCoder:(NSCoder*)decode;
#end
And the .m:
#import "Woman.h"
#implementation Woman
-(id)initWithFull:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.intervalLength = intervalLength;
self.pmsLength = pmsLength;
self.periodLength = periodLength;
return self;
}
-(id)initWithIntervalnoPMSPeriod:(NSString *)girlname withdate2:(NSDate *)date2 withintervalLength:(NSString *)intervalLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.intervalLength = intervalLength;
return self;
}
-(id)initWithNoInterval:(NSString *)girlname withdate2:(NSDate *)date2 withperiodLength:(NSString *)periodLength withpmsLength:(NSString *)pmsLength {
self = [super init];
self.girlname = girlname;
self.date2 = date2;
self.pmsLength = pmsLength;
self.periodLength = periodLength;
return self;
}
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
self.girlname = [coder decodeObjectForKey:#"girlname"];
self.date2 = [coder decodeObjectForKey:#"date2"];
self.intervalLength = [coder decodeObjectForKey:#"intervalLength"];
self.pmsLength = [coder decodeObjectForKey:#"pmsLength"];
self.periodLength = [coder decodeObjectForKey:#"periodLength"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:_girlname forKey:#"girlname"];
[coder encodeObject:_date2 forKey:#"date2"];
[coder encodeBool:_intervalLength forKey:#"intervalLength"];
[coder encodeBool:_pmsLength forKey:#"pmsLength"];
[coder encodeBool:_periodLength forKey:#"periodLength"];
}
#end
Here is also a breakpoint screenshot which shows that the newest object (index 2) has values before it is stores in NSDefaults.
UPDATE: After switching "nameofgirl" and the interval string, the interval string worked, but nameofgirl returned nil. So it's only the first two values working for some reason.
intervalLength, pmsLength and periodLength are NSString objects. Use encodeObject: to encode them.

Objective-C addObject seems to put object into all array indices

I am trying to learn how to make simple classes.
So far I am not getting the results expected using addObject and my class.
Here is what I have:
In my view controller:
#import "onoffclass.h"
In its viewDidLoad:
NSMutableArray *inTable;
onoffclass *therec;
onoffclass *readrec;
inTable = [NSMutableArray array];
therec = [[onoffclass alloc]init];
readrec = [[onoffclass alloc]init];
for (int lop=0;lop<3;lop++){
therec.parsedID = [NSString stringWithFormat:#"%i",lop];
[inTable addObject:therec];
NSLog(#"lop=%i onoff.parsedID=%#",lop,therec.parsedID);
for (int z=0;z<[inTable count];z++){
readrec = inTable[z];
NSLog(#" inTable[%i] parsedID=%#",z,readrec.parsedID);
}
}
In my onoffclass.h:
#interface onoffclass : NSObject
#property NSString *parsedID;
#property NSString *parsedOn;
#property NSString *parsedOff;
#property NSString *parsedAdj;
#property NSString *parsedRoom;
#property NSString *parsedBuilding;
#property NSString *parsedWho;
#property NSString *parsedInfo;
#property NSString *parsedBillable;
-(onoffclass*)initWithSomeString: (NSString*)blah AndSomeNum: (int)num;
-(NSString*)description;
#end
In my onoffclass.m:
#import <Foundation/Foundation.h>
#import "onoffclass.h"
#implementation onoffclass {
NSString *_parsedID;
NSString *_parsedOn;
NSString *_parsedOff;
NSString *_parsedAdj;
NSString *_parsedRoom;
NSString *_parsedBuilding;
NSString *_parsedWho;
NSString *_parsedInfo;
NSString *_parsedBillable;
}
-(onoffclass*)initWithSomeString: (NSString*)blah AndSomeNum: (int)num {
self = [super init];
_parsedID = blah;
_parsedOn = #"on";
_parsedOff = #"off";
_parsedAdj = #"adj";
_parsedRoom = #"room";
_parsedBuilding = #"building";
_parsedWho = #"who";
_parsedInfo = #"info";
_parsedBillable = #"billable";
return self;
}
-(NSString*)description {
return [NSString stringWithFormat: #"%#", _parsedID];
}
#end
Here is the output:
lop=0 onoff.parsedID=0
inTable[0] parsedID=0
lop=1 onoff.parsedID=1
inTable[0] parsedID=1
inTable[1] parsedID=1
lop=2 onoff.parsedID=2
inTable[0] parsedID=2
inTable[1] parsedID=2
inTable[2] parsedID=2
Why does it appears that addObject is updating all array indices and how do I fix this?
Thanks,
Dale
You are creating one instance of onoffclass (by the way class names should start with a capital letter) then you are adding the same instance again and again in the loop. Since classes are reference types changing a property affects all occurrences of the same instance.
Solution is to put the line to create an instance in the loop
for (int lop = 0; lop < 3; lop++) {
therec = [[onoffclass alloc] init];
...

NSMutableDictionary crashes with "mutating message sent to immutable object"

I have a class that has a NSMutableDictionary as a property:
#interface Alibi : NSObject <NSCopying>
#property (nonatomic, copy) NSMutableDictionary * alibiDetails;
#end
With the following constructor:
- (Alibi *)init
{
self = [super init];
_alibiDetails = [NSMutableDictionary dictionary];
return self;
}
and copy method:
- (Alibi *)copyWithZone:(NSZone *)zone
{
Alibi *theCopy = [[Alibi alloc] init];
theCopy.alibiDetails = [self.alibiDetails mutableCopy];
return theCopy;
}
When I try to call setObject:ForKey: I get a runtime error mutating method sent to immutable object.
I have the Alibi object declared in the view controller as #property (copy, nonatomic) Alibi * theAlibi; and I initialize it with self.theAlibi = [[Alibi alloc] init]; in viewDidLoad.
The line which crashes is:
NSString * recipient;
recipient = #"Boss";
[self.theAlibi.alibiDetails setObject:recipient forKey:#"Recipient"];
Please let me know what I am doing wrong here. I am coding for iOS 5 on iPhone.
You have a 'copy' property, which means exactly that - your NSMutableDictionary will get the -copy method called and return a regular NSDictionary before being assigned to the synthesized instance variable. This thread provides some information on some of your options as to solving this.
For the sake of completing this thread I will include my revised Alibi class below, this works as I require it to. If anyone notices any memory leaks or other issues, that would be appreciated.
#implementation Alibi
NSMutableDictionary *_details;
- (Alibi *)init
{
self = [super init];
_details = [NSMutableDictionary dictionary];
return self;
}
- (NSMutableDictionary *)copyDetails
{
return [_details mutableCopy];
}
- (NSMutableDictionary *)setDetails:(NSMutableDictionary *)value
{
_details = value;
return value;
}
- (void)addDetail:(id)value forKey:(id)key
{
[_details setObject:value forKey:key];
}
- (id)getDetailForKey:(id)key
{
return [_details objectForKey:key];
}
- (Alibi *)copyWithZone:(NSZone *)zone
{
Alibi *theCopy = [[Alibi alloc] init];
theCopy.serverId = [self.serverId copyWithZone:zone];
theCopy.user = [self.user copyWithZone:zone];
theCopy.startTime = [self.startTime copyWithZone:zone];
theCopy.endTime = [self.endTime copyWithZone:zone];
[theCopy setDetails:[self copyDetails]];
return theCopy;
}
#end

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];
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
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.