07-27-2011, 01:56 PM
#1 (permalink )
Registered Member
Join Date: Jul 2011
Posts: 1
Weird NSArray Results :S
Hey, I am having real trouble with my program atm, and I really have no clue how to fix it. I believe I have tried almost everything, nevertheless I know it will probably end up being a stupid mistake in the end. Basically I am making a program that takes two parents (human object instances) and they have blood types (bloodType instances) and the program calculates what the baby will have. It stores these values in an NSArray and then it randomly chooses which one of the four possibilities the baby will actually have.
The problem however is that whatever the last entry is in the NSArray, that populates the whole array. The rest of the program works, it chooses a random number from the array and everything, but the array is populated by the same objects.
Anyway, here is the code, and please help if you can.
//To choose a random object from the array
#import "ArrayCategory.h"
@implementation NSArray (ArrayCategory)
-(id) tpRandomObject
{
long int x = arc4random();
int y = x % 4;
return [self objectAtIndex: y];
}
@end
#import <Cocoa/Cocoa.h>
@interface NSArray (ArrayCategory)
-(id) tpRandomObject;
@end
--------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import "ArrayCategory.h"
#import "BloodType.h"
@class BloodType;
@interface Human : NSObject <NSCoding>
{
BloodType * blood;
int nos;
}
-(Human *) makeBabyWith: (Human *) other;
-(id) init;
-(void) dealloc;
-(void) encodeWithCoder: (NSCoder *) aCoder;
-(id) initWithCoder: (NSCoder *) aDecoder;
@property (nonatomic, retain) BloodType * blood;
@property int nos;
@end
#import "Human.h"
@implementation Human
-(Human *) makeBabyWith: (Human *) other
{
Human * baby = [[Human alloc]init];
NSArray * arr = [NSArray arrayWithArray:[self.blood getAllCombosWith: other.blood]];
[arr writeToFile: @"/Users/theopavlakou/Desktop/blood.txt" atomically: YES]; //Why not working
//Only works in main
baby.blood = [arr tpRandomObject];
//[arr release];
//baby.blood = [[self.blood getAllCombosWith: other.blood] tpRandomObject];
return baby;
}
-(id) init
{
if (self =[super init])
{
blood = [[BloodType alloc] init ];
nos = 3;
}
return (self);
}
-(void) dealloc
{
[blood release];
[super dealloc];
}
-(NSString *) description
{
return [self.blood description];
}
-(void) encodeWithCoder: (NSCoder *) coder
{
[coder encodeObject: blood forKey: @"blood"];
[coder encodeInt:nos forKey:@"nos"];
}
-(id) initWithCoder: (NSCoder *) decoder
{
if (self = [super init])
{
self.blood = [decoder decodeObjectForKey:@"blood"];
self.nos = [decoder decodeIntForKey:@"nos"];
}
return (self);
}
@synthesize blood, nos;
@end
--------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import "ArrayCategory.h"
typedef enum {O = 1, A, B} bloodType;
@interface BloodType : NSObject <NSCoding>
{
bloodType allele1;
bloodType allele2;
int number;
}
-(NSString *) alleleAsString;
-(NSMutableArray *) getAllCombosWith: (BloodType *) otherBlood;
-(void) encodeWithCoder: (NSCoder *) aCoder;
-(id) initWithCoder: (NSCoder *) aDecoder;
@property bloodType allele1;
@property bloodType allele2;
@property int number;
@end
#import "BloodType.h"
@implementation BloodType
-(NSMutableArray *) getAllCombosWith: (BloodType *) otherBlood
{
NSMutableArray * array = [NSMutableArray arrayWithCapacity:4];
BloodType * tempBlood = [[BloodType alloc]init];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
//NSLog(@"Retain count is: %@", [tempBlood retainCount]);
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
NSLog(@"Retain count is: %i", [array retainCount]);
for (BloodType * blood in array) //Fast enumeration
{
NSLog(@"%@", blood);
}
NSArray * array2 = [NSArray arrayWithObjects: @"I", @"am", @"Theo", nil];
if ([array2 writeToFile: @"/Users/theopavlakou/Desktop/blood.txt" atomically: YES] == NO)
{NSLog(@"Not Successful");}
if ([array writeToFile: @"/Users/theopavlakou/Desktop/blood.txt" atomically: YES] == NO)
{NSLog(@"Not Successful");}//Why not working? Because can't print descriptions, needs NSStrings.
[tempBlood release];
NSArray * arr2 = [NSArray arrayWithArray: array];
[arr2 writeToFile: @"/Users/theopavlakou/Desktop/blood.txt" atomically: YES];
return array;
}
-(NSString *) alleleAsString
{
//NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt: 0],@"O", [NSNumber numberWithInt: 1], @"A",[NSNumber numberWithInt: 2], @"B", nil];
NSMutableString * a1 = [[NSMutableString alloc]init];
NSMutableString * a2 = [[NSMutableString alloc]init];
switch (self.allele1) {
case O:
[a1 appendString: @"O"];
break;
case A:
[a1 appendString: @"A"];
break;
case B:
[a1 appendString: @"B"];
break;
default:[a1 appendString: @"***There was an error!***"];
break;
}
//NSLog(@"this is %@", a1);
switch (self.allele2) {
case O:
[a2 appendString: @"O"];
break;
case A:
[a2 appendString: @"A"];
break;
case B:
[a2 appendString: @"B"];
break;
default:[a2 appendString: @"***There was an error!***"];
break;
}
//NSLog(@"this is %@", a2);
[a1 autorelease];
[a2 autorelease];
NSString * retString = [NSString stringWithFormat: @"blood genotype is %@ %@", a1 , a2];
[retString autorelease];
return (retString);
//return (@"My blood genotype is %@ %@", [dict objectForKey: [NSNumber numberWithInt: self.allele1]],
// [dict objectForKey: [NSNumber numberWithInt: self.allele2]]); //Check how to fix
}
-(NSString *) description
{
return [self alleleAsString];
}
-(void) encodeWithCoder: (NSCoder *) coder
{
[coder encodeInt: allele1 forKey:@"allele1"];
[coder encodeInt: allele2 forKey:@"allele2"];
[coder encodeInt: number forKey:@"number"];
}
-(id) initWithCoder: (NSCoder *) decoder
{
if (self = [super init])
{
self.allele1 = [decoder decodeIntForKey: @"allele1"];
self.allele2 = [decoder decodeIntForKey: @"allele2"];
self.number = [decoder decodeIntForKey: @"number"];
}
return (self);
}
@synthesize allele1, allele2, number;
@end
That's the code, please if you can help, I am really getting frustrated over this.
Thank you
07-27-2011, 04:19 PM
#2 (permalink )
Registered Member
Join Date: Oct 2010
Location: Atlanta, GA
Posts: 148
Use code tags...hint...it's the button above the textField you are typing in that looks like this # .
You have a lot of code and it's hard to read. put the tag around it and we'll be much happier trying to read it.
07-27-2011, 04:58 PM
#3 (permalink )
Registered Member
Join Date: Apr 2011
Posts: 136
Possibly the best method name I have ever seen:
Code:
- (Human *)makeBabyWith:(Human *)other;
08-04-2011, 12:00 AM
#4 (permalink )
Registered Member
Join Date: Aug 2011
Location: Chicago
Age: 22
Posts: 2
It looks like there is an object allocation issue in the getAllCombosWith method. There are supposed to be four instances of the BloodType object, but only one is allocated. When the tempBlood.allele1 and tempBlood.allele2 methods are invoked, they change the original object instead of creating a new object. The array ends up with four pointers to the same object. Instead of doing this:
Code:
-(NSMutableArray *) getAllCombosWith: (BloodType *) otherBlood
{
NSMutableArray * array = [NSMutableArray arrayWithCapacity:4];
BloodType * tempBlood = [[BloodType alloc]init];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
//NSLog(@"Retain count is: %@", [tempBlood retainCount]);
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood);
[array addObject:tempBlood];
Change the code to this:
Code:
-(NSMutableArray *) getAllCombosWith: (BloodType *) otherBlood
{
NSMutableArray * array = [NSMutableArray arrayWithCapacity:4];
BloodType * tempBlood1 = [[BloodType alloc]init];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood1);
[array addObject:tempBlood1];
//NSLog(@"Retain count is: %@", [tempBlood retainCount]);
BloodType * tempBlood2 = [[BloodType alloc]init];
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood2);
[array addObject:tempBlood2];
BloodType * tempBlood3 = [[BloodType alloc]init];
tempBlood.allele1 = self.allele1;
tempBlood.allele2 = otherBlood.allele2;
NSLog(@"%@", tempBlood3);
[array addObject:tempBlood3];
BloodType * tempBlood4 = [[BloodType alloc]init];
tempBlood.allele1 = self.allele2;
tempBlood.allele2 = otherBlood.allele1;
NSLog(@"%@", tempBlood4);
[array addObject:tempBlood4];
Hope this helps.
Thread Tools
Display Modes
Linear Mode
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
» Advertisements
» Online Users: 478
16 members and 462 guests
7twenty7 , AlanFloyd , AppsBlogger , David-T , HemiMG , iAppDeveloper , imac74 , Jaxen66 , lovoyl , Music Man , mutantskin , Paul Slocum , SLIC , solardrift , unicornleo , usernametaken
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,683
Threads: 94,131
Posts: 402,932
Top Poster: BrianSlick (7,990)
Welcome to our newest member, unicornleo