I apologize for the lengthy question, ill try demonstrating the problem with examples.
I have three objects
Disease
Compound
Comdis
I am storing the list of Diseases and Compounds in respective classes.
The relations between Compounds and Diseases are to be stored in a list of objects called Comdis, Comdis stores pairs of (COMPOUND,DISEASE).
The example infromation that is to be stored in objects are.
DISEASES
index acronim fullname
1 AML, Acute Myelogenous Leukemia
2 PV, Polycytemia Vera
3 MF, Mielofibrosis
COMPOUNDS
index acronim fullname
1 LBH589, Panobinostat
2 INC424, Ruxolitinib
3 BKM120, Buparsinib
RELATIONS (COMDIS)
index disease compound
1 ( 0 , 1 )
2 ( 0 , 2 )
3 ( 0 , 3 )
4 ( 1 , 1 )
5 ( 1 , 2 )
6 ( 1 , 3 )
7 ( 2 , 1 )
8 ( 2 , 2 )
9 ( 2 , 3 )
My disease.h looks like this.
#interface disease: NSObject
{
NSString __strong *acronim;
NSString __strong *fullname;
int backcolor;
UIImage __strong *background;
}
#property (nonatomic) int backcolor;
#property (nonatomic, strong) UIImage *background;
#property (nonatomic, strong) NSString *acronim;
#property (nonatomic, strong) NSString *fullname;
#property NSMutableArray *list;
- (id)initWithDiseaseList;
- (int)getIndexByAcronim:(NSString *)acronim;
#end
disease.m has the following code
#import "disease.h"
#implementation disease
#synthesize acronim, fullname, backcolor, background;
-(id)initWithDiseaseList {
disease *aml = [[disease alloc] init];
[aml setAcronim:#"AML"];
[aml setFullname:#"Acute Myelogenous Leukemia"];
disease *pv = [[disease alloc] init];
[pv setAcronim:#"PV"];
[pv setFullname:#"Polycytemia Vera"];
disease *mf = [[disease alloc] init];
[mf setAcronim:#"MF"];
[mf setFullname:#"Mielofibrosis"];
NSMutableArray *array = [NSMutableArray array];
[array addObject:aml];
[array addObject:pv];
[array addObject:mf];
self.list = array;
return self;
}
- (int)getIndexByAcronim:(NSString *)accr {
NSArray *array = self.list;
for(int i = 0; i < [array count]; i++) {
disease *disease = [array objectAtIndex:i];
if(disease.acronim == accr) {
return i;
}
}
return -1;
}
#end
my compound.m is very similar to disease object.
now in comdis i want to store relations.
my comdis.h looks like this
#interface comdis: NSObject
{
int *icompound;
int *idisease;
}
#property (nonatomic,) int *icompound;
#property (nonatomic,) int *idisease;
#property NSMutableArray *list;
- (id)initWithComdisList;
#end
and this is my comdis.m
#import "comdis.h"
#import "compound.h"
#import "disease.h"
#implementation comdis
#synthesize idisease, icompound;
- (id)initWithComdisList {
compound *comp = [[compound alloc] initWithCompoundList];
disease *dis = [[disease alloc] initWithDiseaseList];
NSArray *compoundArray = comp.list;
NSArray *diseaseArray = dis.list;
NSMutableArray *array = [NSMutableArray array];
for(int i = 0; i < [diseaseArray count]; i++) {
for(int j = 0; j < [compoundArray count]; j++) {
int iCompoundIndex = [compoundArray indexOfObject:compoundArray[j]];
int iDiseaseIndex = [diseaseArray indexOfObject:diseaseArray[i]];
comdis *com = [[comdis alloc] init];
[com setIdisease:&iDiseaseIndex];
[com setIcompound:&iCompoundIndex];
[array addObject:com];
}
}
comdis *comdisObj = [self.list objectAtIndex:1];
int idis = *(comdisObj.idisease);
int icom = *(comdisObj.icompound);
NSLog(#"%d", idis);
NSLog(#"%d", icom);
return self;
}
#end
The problem is if i try printing the value of idis or icom it always prints 2 regardless of objectAtIndex value i give. it seems the value in loop is being overwritten and it always takes the last value of loop, i am a beginner to objective-c and will appreciate if someone could put some light on what is wrong with my code.
Sorry again for lengthy explanation and code.
[com setIdisease:&iDiseaseIndex];Because all comdis object's property disease and compound refer to the same address, they all equal to the value of last added object. To overcome this problem, you may use int property instead of *int in comdis.
Related
I am new to objective c and having some problem with nsmutableArray.I have button and two textfields on my gui and i want that when i click on button the strings from textfields should be added to my existing array. But the problem is that when i click on button it always create new array.Help anybody.
my button code in myfile.m is as follows:
NSMutableArray* myArray = [NSMutableArray array];
NSString *strr=[textf stringValue];
NSString *strr1=[textf1 stringValue];
// [myArray addObject:strr]; // same with float values
// [myArray addObject:strr1];
[myArray addObject:strr];
[myArray addObject:strr1];
int i,j=0;
int count;
for (i = 0, count = [myArray count]; i < count; ){
NSString *element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element);
}
Because you always create new array in this line:
NSMutableArray* myArray = [NSMutableArray array];
Make your array as property of your class object. Example:
#interface MyClass ()
#property (nonatomic, strong) NSMutableArray * array;
#end
#implementation MyClass
- (id)init {
self = [super init];
if ( self ) {
_array = [NSMutableArray array];
}
return self;
}
- (IBAction)onButtonClick {
NSString *strr = [textf stringValue];
NSString *strr1 = [textf1 stringValue];
[self.array addObject:strr];
[self.array addObject:strr1];
for ( int i = 0; i < [myArray count]; i++ ) {
NSString * element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element);
}
}
#end
This question already has answers here:
Access NSMutableArray from a different class
(3 answers)
Closed 10 years ago.
This is how my Entity classes look:
BaseDataEntity.h
#import -Foundation/Foundation.h
#interface BaseDataEntity : NSObject
#property (assign) NSMutableArray *cbxDataList;
#property (assign) NSString *resaultText;
#end
BaseDataEntity.m
#import "BaseDataEntity.h"
#implementation BaseDataEntity
#synthesize cbxDataList = _cbxDataList;
#synthesize resaultText = _resaultText;
#end
And this is how I try to access them:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification{
BaseDataEntity *aBaseDataEntity = [[BaseDataEntity alloc] init];
[self setBaseDataEntity:aBaseDataEntity];
}
-(IBAction)ReadPort:(id)sender {
NSMutableArray* array = [[NSMutableArray alloc] init];
for (int i=0; i<10; i++) {
NSString *temp = [NSString stringWithFormat:#"Test %d", i];
[array addObject:temp];
}
[self.baseDataEntity setCbxDataList:array];
NSLog(#" cbxDataList count = %lu",[array count]);
[array release];
[self.baseDataEntity setResaultText:#"Test"];
[self updateUserInterface:TRUE];
}
-(void)updateUserInterface:(BOOL)piClear{
NSString *textValue = [NSString stringWithFormat:#"%#"
,[self.baseDataEntity resaultText]];
if([self.ResaultTextField stringValue] != nil && !piClear){
textValue = [NSString stringWithFormat:#"%#\n%#", textValue
,[self.ResaultTextField stringValue]];
}
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
[self.baseDataEntity.cbxDataList value]];
for (int i = 0; i < [array count]; i++) {
textValue = [NSString stringWithFormat:#"%#\n%#", textValue
,[array objectAtIndex:i]];
}
[array release];
[self.ResaultTextField setStringValue:textValue];
}
The problem is that I can update resaultText and have access to the value of this. But cbxDataList value is always empty.
You should use retain instead of assign to increase the retain count of cbxDataList.
#property (retain) NSMutableArray *cbxDataList;
Please note, that the object needs to be released sometime, or you could have a memory leak.
In the below function,
-(void)updateUserInterface:(BOOL)piClear
The array creation is wrong.
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
[self.baseDataEntity.cbxDataList value]];
The above code nneeds to be replaced by,
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
self.baseDataEntity.cbxDataList];
Try these :
#property (retain) NSMutableArray *cbxDataList;
#property (assign) NSString *resaultText;
And in -(void)applicationDidFinishLaunching:(NSNotification *)aNotification
alloc+init both of them.
I've this model:
#interface Data : NSObject
#property (nonatomic, assign) int Period;
#property (nonatomic, assign) NSDate *Start;
#property (nonatomic, assign) NSDate *End;
#end
#implementation Data
#synthesize Period, Start, End;
#end
I add data in mutable array.
#property (strong, nonatomic) NSMutableArray* myArray;
self.myArray = [NSMutableArray arrayWithCapacity:0];
Data *element =[ [Data alloc] init];
element.Period = 1;
element.Start = dateStart1;
element.End = dateEnd1;
[self.myArray addObject:element];
element.Period = 2;
element.Start = dateStart2;
element.End = dateEnd2;
[self.myArray addObject:element];
element.Period = 3;
element.Start = dateStart3;
element.End = dateEnd3;
[self.myArray addObject:element];
Why when extract Period from array i receive only the last element x 3 ???
Data * NumElement = [self.myArray valueForKey:#"Period"];
NSLog(#"All period: %#", NumElement);
and i receive 3 3 3 instead of 1 2 3 ?
You instantiate a single object, add it to the array, then change that same object and add it again to the array, etc. The array ends up holding 3 references to the same object, with the values last assigned to it.
Try this:
Data *element1 =[ [Data alloc] init];
element1.Period = 1;
element1.Start = dateStart1;
element1.End = dateEnd1;
[self.myArray addObject:element1];
Data *element2 =[ [Data alloc] init];
element2.Period = 2;
element2.Start = dateStart2;
element2.End = dateEnd2;
[self.myArray addObject:element2];
Data *element3 =[ [Data alloc] init];
element3.Period = 3;
element3.Start = dateStart3;
element3.End = dateEnd3;
[self.myArray addObject:element3];
That's because you're putting the same object into your array over and over again. No matter how many times you add it, no matter which of its properties you change, it's the same object.
You need to instantiate an object for each set of data.
i have one array named invoiceInfo1 & i pass it to another array named allInfo.
But I want for different index of invoiceInfo ,the different array is created & pass it to allInfo.
Mycode is as follow:
for (int i=0; i<[userdata count]; i++) {
NSLog(#" userdata count :%d",[userdata count]);
invoiceInfo1 = [NSMutableArray arrayWithObjects:[[userdata objectAtIndex:i]valueForKey:#"fname"], [[userdata
objectAtIndex:i]valueForKey:#"name"],
[[userdata objectAtIndex:i]valueForKey:#"address"],
[[userdata objectAtIndex:i]valueForKey:#"city"], nil];
NSLog(#" info1 is:%#",invoiceInfo1); // invoiceInfo get overwrite when loop execute
NSMutableArray* allInfo = [NSMutableArray arrayWithObjects:headers,invoiceInfo1 , nil];
// HERE I Want Generate New Array of different index of invoiceInfo1 & pass it to allInfo
}
Create a NSObject class with header and info array:
#interface AllInfo: NSObject
{
NSMutableArray *header;
NSMutableArray *info;
}
#property (nonatomic, retain) NSMutableArray *header;
#property (nonatomic, retain) NSMutableArray *info;
#end
#implementation AllInfo
#synthesize header;
#synthesize info;
#end
Then implement this code:
allInfo = [[NSMutableArray alloc] init];
for (int i=0; i<[userdata count]; i++) {
NSLog(#" userdata count :%d",[userdata count]);
NSMutableArray *invoiceInfo1 = [[NSMutableArray alloc] init];
[invoiceInfo1 addObject:[userdata objectAtIndex:i]valueForKey:#"fname"]];
[invoiceInfo1 addObject:[userdata objectAtIndex:i]valueForKey:#"name"]];
[invoiceInfo1 addObject:[userdata objectAtIndex:i]valueForKey:#"address"]];
[invoiceInfo1 addObject:[userdata objectAtIndex:i]valueForKey:#"city"]];
NSLog(#" info1 is:%#",invoiceInfo1); // invoiceInfo get overwrite when loop execute
AllInfo *newInfo = [[AllInfo alloc] init];
newInfo.header = headers;
newInfo.info = invoiceInfo1;
[allInfo addObject:newInfo];
// HERE I Want Generate New Array of different index of invoiceInfo1 & pass it to allInfo
}
Hope this will help.
I wonder if its possible to make a for loop or something similar when you need to assign a lot of values to variables?
store.item1 = #"asdasd";
store.item2 = #"asdasd";
store.item3 = #"asdasd";
store.item4 = #"asdasd";
store.item5 = #"asdasd";
store.item6 = #"asdasd";
store.item7 = #"asdasd";
store.item8 = #"asdasd";
store.item9 = #"asdasd";
something like:
for (int i = 0; i < 10; i++)
{
store.item%i = #"asds";
}
Thanks in advance
You can use Key-Value Coding to do that:
for (int i = 0; i < 10; i++)
{
[store setValue:#"asdfasd" forKeyPath:[NSString stringWithFormat:#"item%d", i]];
}
But as the other answers advised ... this might not be what you really want if you're indeed working on a store.
As JiaYow said, use KVC.
This is a working exapmle:
#import <Foundation/Foundation.h>
#interface Store : NSObject
#property (nonatomic, copy) NSString *item1;
#property (nonatomic, copy) NSString *item2;
#property (nonatomic, copy) NSString *item3;
#property (nonatomic, copy) NSString *item4;
#property (nonatomic, copy) NSString *item5;
#property (nonatomic, copy) NSString *item6;
#end
#implementation Store
#synthesize item1, item2, item3, item4, item5, item6;
#end
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
Store *store = [[Store alloc] init];
for (int i = 1; i < 7; i++)
{
[store setValue:#"asdfasd" forKeyPath:[NSString stringWithFormat:#"item%d", i]];
}
[p release];
}
Cheers,
Johannes
If you have a sequence of variables, use NSArray to store them, not individual instance variables.