In this method I add the content of UITextFields, images and other strings in a sqlite database. Everything works fine. I mean, when i press the "Add" button, the "OK" image appear, the sound play and all the contents are added to the database (I can check restarting the application). But after all of this, I have this error in the "main.m"
This is the method:
-(IBAction)addItem:(id)sender { //gestione pulsante aggiunta elemento
if (([itemNameField.text length] == 0) || ([priceField.text length] == 0) || ([priceField.text doubleValue] == 0.0) || ((incomeOutcome.selectedSegmentIndex != 0) && (incomeOutcome.selectedSegmentIndex != 1))) {
if ([itemNameField.text length] == 0) {
statusLabel.text = [[NSString alloc] initWithFormat: #"Specificare un nome."];
} else if (([priceField.text length] == 0) || ([priceField.text doubleValue] == 0.0)) {
statusLabel.text = [[NSString alloc] initWithFormat: #"Specificare un prezzo."];
} else if ((incomeOutcome.selectedSegmentIndex != 0) && (incomeOutcome.selectedSegmentIndex != 1)) {
statusLabel.text = [[NSString alloc] initWithFormat: #"Specificare \"Income/Outcome\" ."];
}
if (!categoriaLabel.hidden) {
[self hideThemAll];
}
[incomeOutcome setSelectedSegmentIndex:-1];
statusLabel.hidden = NO;
error = true;
[self playSound];
[ok setImage:[UIImage imageNamed:#"error.png"]];
ok.hidden = NO;
return;
}
//apriamo il database
sqlite3 *db;
int dbrc; //Codice di ritorno del database (database return code)
iWalletAppDelegate *appDelegate = (iWalletAppDelegate*) [UIApplication sharedApplication].delegate;
const char *dbFilePathUTF8 = [appDelegate.dbFilePath UTF8String];
dbrc = sqlite3_open(dbFilePathUTF8, &db);
if (dbrc) {
NSLog(#"Impossibile aprire il Database!");
return;
}
//database aperto! Inseriamo valori nel database.
sqlite3_stmt *dbps; //Istruzione di preparazione del database
NSString *insertStatementsNS;
if (incomeOutcome.selectedSegmentIndex == 0) {
insertStatementsNS = [NSString stringWithFormat: #"insert into \"shoppinglist\" (item, price, groupid, incout, path, dateadded) values (\"%#\", \"%#\", \"Entrata\", %d, \"%#\", DATETIME('NOW'))", itemNameField.text, priceField.text, incomeOutcome.selectedSegmentIndex, imagePath];
} else if ([categoryNameField.text length] != 0) {
insertStatementsNS = [NSString stringWithFormat: #"insert into \"shoppinglist\" (item, price, groupid, incout, path, dateadded) values (\"%#\", \"%#\", \"%#\", %d, \"%#\", DATETIME('NOW'))", itemNameField.text, priceField.text, categoryNameField.text, incomeOutcome.selectedSegmentIndex, imagePath];
} else {
insertStatementsNS = [NSString stringWithFormat: #"insert into \"shoppinglist\" (item, price, groupid, incout, path, dateadded) values (\"%#\", \"%#\", \"Varie\", %d, \"%#\", DATETIME('NOW'))", itemNameField.text, priceField.text, incomeOutcome.selectedSegmentIndex, imagePath];
}
const char *insertStatement = [insertStatementsNS UTF8String];
dbrc = sqlite3_prepare_v2(db, insertStatement, -1, &dbps, NULL);
dbrc = sqlite3_step(dbps);
//faccio pulizia rilasciando i database
sqlite3_finalize(dbps);
sqlite3_close(db);
// Pulisci i campi e indica successo nello status
statusLabel.hidden = NO;
statusLabel.text = [[NSString alloc] initWithFormat: #"Aggiunto %#", itemNameField.text];
itemNameField.text = #"";
priceField.text = #"";
categoryNameField.text = #"";
imagePath = #"";
[incomeOutcome setSelectedSegmentIndex:-1];
error = false;
[self hideThemAll];
[self playSound];
[ok setImage:[UIImage imageNamed:#"ok.png"]];
ok.hidden = NO;
nome = #"";
prezzo =#"";
[photoPreview setImage:[UIImage imageNamed:#"noPhoto.png"]];
[[self parentViewController]dismissModalViewControllerAnimated:YES];
}
EDIT
Thanks to Isaac I (maybe) found the issue: I wasn't retaining the picture I took from the camera.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
int r = arc4random() % 9999;
NSDate *date = [NSDate date];
NSString *photoName = [dateNameFormatter stringFromDate:date];
photoName = [photoName stringByAppendingString:[NSString stringWithFormat:#"%d", r]];
if (imagePath) {
[imagePath release];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", photoName]];
[imagePath retain];
UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];
// ----- CODE FOR SCALE THE IMAGE ----- //
if (picture.size.width == 1936) {
picture = [picture scaleToSize:CGSizeMake(480.0f, 720.0f)];
} else {
picture = [picture scaleToSize:CGSizeMake(720.0f, 480.0f)];
}
photoPreview.image = picture;
photoPreview.contentMode = UIViewContentModeScaleAspectFit;
CGRect frame = photoPreview.frame;
if (picture.size.width == 480) {
frame.size.width = 111.3;
frame.size.height =167;
} else {
frame.size.width = 167;
frame.size.height =111.3;
}
photoPreview.frame = frame;
// ----- ----- - END CODE - ----- ----- //
NSData *webData = UIImagePNGRepresentation(picture);
CGImageRelease([picture CGImage]);
[webData writeToFile:imagePath atomically:YES];
[picture retain]; // <-- This little thing here!
//imgPicker = nil;
}
Now it works! But if you can see other problems, please let me notice them.
There is no reason to create NSString like this:
statusLabel.text = [[NSString alloc] initWithFormat: #"Specificare un nome."];
Simply write
statusLabel.text = #"Specificare un nome.";
Maybe it's not a cause of EXC_BAD_ACCESS, but at least you can avoid several memory leaks.
Typically an EXC_BAD_ACCESS occurs when you are trying to access memory that has been deallocated. In your code sample, I don't see any [object release] calls (that's another problem entirely, unless you happen to be using ARC). But my guess it that this error is the result of a call that is being made outside of the scope of this method - something is being released prematurely.
You could paste your entire class, or, consider using the Instruments tool 'Zombies' to identify the dangling pointer which is (probably) causing this.
In my opinion isaac is right. I just want to add one guess. Most likely the error occurs when you invoke
[[self parentViewController]dismissModalViewControllerAnimated:YES];
By this moment, I think, something in you parentViewController is already released, so when you try to show it back, program turns to released variable and gives you a crash.
You can quite easily detect it just with the help of breakpoints.
Related
Trying to split the string in to array, but it is giving error "[__NSArrayI componentsSeparatedByString:]: unrecognized selector sent to instance 0x11741b20'". The string contains the value, that comes from first index of array then the string needs to be split and store in array.
This is array value.
mcommarr:(
":comment",
":comment",
":comment"
NSString *strr = [[NSString alloc]init];
strr = [self.mCommArr objectAtIndex:indexVal];
NSArray *arr2 = [str componentsSeparatedByString:#","];
Here is the complete method in which i am using this.
-(void)loadData:(int)indexVal;
{
indexVal=serialIndexVal;
serialIndexVal++;
NSLog(#"arrLike:%d", [self.mArrLike count]);
NSLog(#"arrPid:%d", [self.mArrPid count]);
status = [NSString stringWithFormat:#"get"];
[self.mButtonsStatusDict setObject:status forKey:#"status"];
[self.mButtonsPidDict setObject:[self.mArrPid objectAtIndex:indexVal] forKey:#"pid"];
[self.activityIndicator startAnimating];
#try
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *status = [NSString stringWithFormat:#"get"];
[self.mButtonsStatusDict setObject:status forKey:#"status"];
[self.mButtonsPidDict setObject:[self.mArrPid objectAtIndex:indexVal] forKey:#"pid"];
self.mButtonsCommentsDict = [MyEventApi showComments:self.mButtonsPidDict];
self.mButtonsDict = [MyEventApi likeDislike:self.mButtonsUidDict post:self.mButtonsPidDict postStatus:self.mButtonsStatusDict];
dispatch_sync(dispatch_get_main_queue(), ^{
[self.activityIndicator stopAnimating];
NSLog(#"buttons data dict:%#", self.mButtonsDict);
if([self.mButtonsDict count] == 0)
{
NSLog(#"server problem no response");
[self.mArrLike addObject: #"0"];
[self.mArrDislike addObject: #"0"];
}else{
[self.mArrLike addObject: [self.mButtonsDict valueForKey:#"like"]];
[self.mArrDislike addObject: [self.mButtonsDict valueForKey:#"dislike"]];
}
if([self.mButtonsCommentsDict count] == 0)
{
NSLog(#"server problem no response");
[self.mCommArrTot addObject: #"0"];
}
else{
self.dictComm = [self.mButtonsCommentsDict valueForKey:#"comments"];
[self.mCommArr addObject:[self.dictComm valueForKey:#"comment"]];
NSLog(#"count:%d",[self.mCommArr count]);
// NSString *strTot = [NSString stringWithFormat:#"%d",tot];
// [self.mCommArrTot addObject:strTot];
NSLog(#"dictcomm:%#", self.dictComm );
NSLog(#"mcommarr:%#", [self.mCommArr objectAtIndex:indexVal]);
strr = [[NSString alloc]init];
strr = [self.mCommArr objectAtIndex:indexVal];
//NSString *strr = [[NSString stringWithFormat:#"%#", [self.mCommArr objectAtIndex:indexVal]];
// NSArray *arr1 = [self string:strr];
// NSArray *splitArray=[self.mCommArr[0] componentsSeparatedByString:#","];
//[strr componentsSeparatedByString:#","];
// NSLog(#"arrSep:%#", arr1);
//int count = [arr1 count];
//NSLog(#"arrcount:%d", count);
// NSString *strTot = [NSString stringWithFormat:#"%d",count];
// [self.mCommArrTot addObject:strTot];
//NSLog(#"mcommarrtot:%#", [self.mCommArrTot objectAtIndex:indexVal]);
}
// NSLog(#"arrLike:%#", [self.mArrLike objectAtIndex:indexVal]);
// NSLog(#"arrDisLike:%#", [self.mArrLike objectAtIndex:indexVal]);
[self.mPublicFriendTable reloadData];
});
});
}
#catch (NSException *exception) {
NSLog(#"main: Caught %#: %#", [exception name], [exception reason]);
}
#finally {
}
}
It get killed when try to split. Why so, i am not getting. If anyone has faced such situation please guide what is wrong her.
You can split the string into an NSArray like below...
NSString *yourString = #"comment,comment,comment";
NSArray *strArray = [yourString componentsSeparatedByString:#","];
NSLog(#"\n\n Array is ==>> %#",strArray);
"[__NSArrayI componentsSeparatedByString:]:
Your error says you tried to send the above method to NSArray, which doesn't has.
As you want to split the array at index 0. you should probably do as :
NSArray *splitArray=[yourArray[0] componentsSeparatedByString:#","];
Here yourArray is the array that you get from Server.
NSString *strr = [[NSString stringWithFormat:#"%#", [self.mCommArr objectAtIndex:indexVal]];
NSArray *arr2 = [strr componentsSeparatedByString:#","];
I think you are passing str right now, which can be an array (as your error points out).
Let me know the results.
while trying to reload table the program giving BAD_EXCESS Signal.
In below code.
-(void)textFieldDidEndEditing:(UITextField *)textField {
NSLog(#"%d",textField.tag);
if (textField.tag == 2) {
IntelligentPillBoxAppDelegate *appdelegate = (IntelligentPillBoxAppDelegate *)[[UIApplication sharedApplication]delegate];
appdelegate.strip1_detail = [pillboxDb get_detail_for_din:value];
[table reloadData];
}
[textField resignFirstResponder];
}
+(NSMutableArray*)get_detail_for_din:(int) din{
NSArray *arrDocPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *strDestPath = [NSString stringWithFormat:#"%#/samplepillbox1.sqlite",[arrDocPath objectAtIndex:0]];
//IntelligentPillBoxAppDelegate *appdelegate = (IntelligentPillBoxAppDelegate *)[[UIApplication sharedApplication]delegate];
//appdelegate.strip1_detail = [[NSMutableArray alloc]init];
NSMutableArray *strip1_detail = [[NSMutableArray alloc]init];
sqlite3 *db;
if(sqlite3_open([strDestPath UTF8String], &db)==SQLITE_OK)
{
NSString *query = [NSString stringWithFormat:#"select * from maintable_master where din =%d ",din];
void* v;
char* err_msg;
sqlite3_stmt *studentStmt;
if(sqlite3_prepare_v2(db, [query UTF8String], -1, &studentStmt, &err_msg)==SQLITE_OK)
{
while (sqlite3_step(studentStmt)==SQLITE_ROW) {
int din = sqlite3_column_int(studentStmt, 0);
NSString *brandname = [NSString stringWithUTF8String: sqlite3_column_text(studentStmt, 1)];
NSString *fullname = [NSString stringWithUTF8String: sqlite3_column_text(studentStmt, 2)];
NSString *strength = [NSString stringWithUTF8String: sqlite3_column_text(studentStmt, 3)];
NSString *medicationtype =[NSString stringWithUTF8String: sqlite3_column_text(studentStmt, 4)];
NSString *presciptionid= [NSString stringWithUTF8String: sqlite3_column_text(studentStmt, 5)];
//float marks = sqlite3_column_double(studentStmt, 2);
//pillbox *st = [[pillbox alloc]init];
//st.Din = sno;
//st.Name = sname;
//NSLog(#"%#",st);
Strip_items *si = [[Strip_items alloc]init];
si.Din = din;
si.BrandName = brandname;
si.FullName = fullname;
si.Strength = strength;
si.MedicationType = medicationtype;
si.PresciptionID = presciptionid;
NSLog(#"%#",si.BrandName);
NSLog(#"%d",si.Din);
NSLog(#"%#",si.FullName);
NSLog(#"%#",si.Strength);
NSLog(#"%#",si.MedicationType);
NSLog(#"%#",si.PresciptionID);
[strip1_detail addObject:si];
}
}
}
return strip1_detail;}
It seems you are not defining all your variables.
Check where value is defined and what its value is.
Also, perhaps you should first resign the responder of the text field and then reload the table view. Depending on your code, the text field whose first responder you resign might not exist any more after a table view reload.
enable zombie objects and it will tell you what error occured.
go to product>edit schems> enabl zombi objects
You are getting BAD_EXCESS in this line...
For more explanation post code of IntelligentPillBoxAppDelegate class
appdelegate.strip1_detail = [pillboxDb get_detail_for_din:value];
I am trying to add elements to a scroll view using this code:
int missionCount;
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *missionsDict = [responseString JSONValue];
/*NSArray *luckyNumbers = [json objectWithString:responseString error:&error];*/
NSLog(#"user Info array is: %#", missionsDict);
// NSDictionary *array = [luckyNumbers1 objectForKey:#"data"];
NSDictionary *missionsData;
missionsData = [missionsDict objectForKey:#"data"];
NSLog(#"missionsData is: %#", missionsData);
NSEnumerator *inner = [missionsData objectEnumerator];
missionsScroll.contentSize = CGSizeMake(768, 1005);
id value;
int badgeY1;
int badgeY2;
int badgeY3;
badgeY1 = 146;
badgeY2 = 188;
badgeY3 = 188;
while((value = [inner nextObject])) {
NSLog(#"value is: %#", value);
NSLog(#"progress is: %#", [value objectForKey:#"progress"]);
NSLog(#"user Info array is: %#", missionsDict);
NSLog(#"name is: %#",[value objectForKey:#"reward_definitions"]);
NSLog(#"missionsData is: %#", missionsData);
NSDictionary *moreData;
moreData = [value objectForKey:#"reward_definitions"];
NSEnumerator *inner2 = [moreData objectEnumerator];
id value2;
int badgeX;
int badgeCount;
badgeX = 0;
badgeCount = 0;
while((value2 = [inner2 nextObject])) {
UIProgressView *progressView;
progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(323, badgeY1, 372, 9)];
float progressValue;
progressValue = ([[[value objectForKey:#"progress"] objectForKey:#"earned"] floatValue] / [[[value objectForKey:#"progress"] objectForKey:#"possible"] floatValue]);
NSLog(#"progressValue is: %f", progressValue);
[progressView setProgress:progressValue];
[missionsScroll addSubview:progressView];
UILabel *missionName;
missionName = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY1, 227, 21)];
missionName.backgroundColor = [UIColor clearColor];
missionName.textColor = [UIColor whiteColor];
missionName.font = [UIFont fontWithName:#"Heiti TC" size:23.0];
missionName.text = [value objectForKey:#"name"];
[missionsScroll addSubview:missionName];
UILabel *requirementsLabel;
requirementsLabel = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY2+25, 227, 21)];
requirementsLabel.backgroundColor = [UIColor clearColor];
requirementsLabel.textColor = [UIColor whiteColor];
requirementsLabel.font = [UIFont fontWithName:#"Papyrus" size:19];
requirementsLabel.text = #"To complete you need:";
[missionsScroll addSubview:requirementsLabel];
NSLog(#"Image URL is: %#", [value2 objectForKey:#"image_url"]);
NSURL *url1 = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [value2 objectForKey:#"image_url"]]];
NSData *urlData1 = [NSData dataWithContentsOfURL:url1];
UIImage *image1 = [UIImage imageWithData:urlData1];
UIImageView *badge = [[UIImageView alloc] initWithImage:image1];
[badge setFrame:CGRectMake(badgeX, badgeY2+70, 70, 70)];
[missionsScroll addSubview:badge];
[badge release];
badgeCount = badgeCount+1;
NSLog(#"badgeCount is: %i", badgeCount);
if (badgeCount == 4) {
NSLog(#"Badge Count = 4");
badgeY2 = badgeY2 +70;
badgeX = 0;
badgeCount = 0;
} else {
NSLog(#"Badge Count ≠ 4");
badgeX = badgeX +75;
}
}
NSLog(#"1st While loop done");
// NSLog(#"reward_definitions is: %#", [missionsData objectForKey:#"id"]);
// NSLog(#"Image URL is: %#", [[value objectForKey:#"reward_definitions"] objectForKey:#"image_url"]);
//if ( [array isKindOfClass:[NSDictionary class]] ) {
badgeY1 = badgeY1 +200;
badgeY2 = badgeY2 +200;
badgeY3 = badgeY3 +200;
missionCount = missionCount+1;
}
NSLog(#"While loops done");
for (int a; missionCount > 4; a = a+1) {
missionsScroll.contentSize = CGSizeMake(776, missionsScroll.contentSize.height+200);
}
Nothing is showing up in the scroll view.
It's not obvious what is happening, but first things to check are where the views are valid (not nil) and that this code is running on the main thread.
Put these in and post the results.
NSLog(#"missionsScroll: %#", (missionsScroll==nil)?#"NIL":#"OK");
NSLog(#"progressView: %#", (progressView==nil)?#"NIL":#"OK");
NSLog(#"missionName: %#", (missionName==nil)?#"NIL":#"OK");
NSLog(#"mainThread: %#", ([NSThread isMainThread])?#"OK":#"Background Thread");
Your code is quite convoluted and very difficult to read. Perhaps you could check if your complicated coordinates calculations work as expected, e.g.
NSLog(#"Frame of badge %#", NSStringFromCGRect(badge.frame));
How many times are your while loops iterating? The outer loop increases the y-position of your labels. But the labels will only be displayed at the end of the run loop / start of the next run loop. If you exit this method with the labels with a high y-value then you'll not see them. (It doesn't matter how many times you change the y-value while you're running this code. The display will only update when it's all done.)
** Correction ** You seem to be adding new views each time around your while loop. So in fact I'd expect you to have multiple copies of the subviews appearing when they finally get displayed.
(There's a lot of code to wade through here. If my answer is way off, you might get better answers, but trimming back some of the code and isolating the issue.)
I'm quite new to Xcode and I have a huge problem with a tutorial I'm working on.
I'm trying to write a simple shopping list, using a sql database.
Actually i finished with the project. I triple checked every single line of code, but for some reason it doesn't want to show me the content of the DB nor write something inside.
Really I have no idea what's wrong with the code...
Writing in the DB:
-(IBAction)addShoppingListItem:(id)sender {
//apriamo il database
if (([itemNameField.text length] == 0) || ([priceField.text length] == 0) || ([priceField.text doubleValue] == 0.0)) {
return;
}
sqlite3 *db;
int dbrc; //Codice di ritorno del database (database return code)
DatabaseShoppingListAppDelegate *appDelegate = (DatabaseShoppingListAppDelegate*) [UIApplication sharedApplication].delegate;
const char *dbFilePathUTF8 = [appDelegate.dbFilePath UTF8String];
dbrc = sqlite3_open(dbFilePathUTF8, &db);
if (dbrc) {
NSLog(#"Impossibile aprire il Database!");
return;
}
//database aperto! Inseriamo valori nel database.
sqlite3_stmt *dbps; //Istruzione di preparazione del database
NSString *insertStatementsNS = [NSString stringWithFormat: #"insert into \"shoppinglist\" (item, price, groupid, dateadded) values (\"%#\", %#, %d, DATETIME('NOW'))", name_field, price_field, [groupPicker selectedRowInComponent:0]];
const char *insertStatement = [insertStatementsNS UTF8String];
dbrc = sqlite3_prepare_v2(db, insertStatement, -1, &dbps, NULL);
dbrc = sqlite3_step(dbps);
//faccio pulizia rilasciando i database
sqlite3_finalize(dbps);
sqlite3_close(db);
// Pulisci i campi e indica successo nello status
statusLabel.text = [[NSString alloc] initWithFormat: #"Aggiunto %#", itemNameField.text];
statusLabel.hidden = NO;
itemNameField.text = #"";
priceField.text = #"";
}
Loading from the database:
-(void)loadDataFromDb {
//apriamo il database
sqlite3 *db;
int dbrc; //Codice di ritorno del database (database return code)
DatabaseShoppingListAppDelegate *appDelegate = (DatabaseShoppingListAppDelegate *) [UIApplication sharedApplication].delegate;
const char *dbFilePathUTF8 = [appDelegate.dbFilePath UTF8String];
dbrc = sqlite3_open(dbFilePathUTF8, &db);
if (dbrc) {
NSLog(#"Impossibile aprire il Database!");
return;
}
//database aperto! Prendiamo i valori dal database.
sqlite3_stmt *dbps; //Istruzione di preparazione del database
NSString *queryStatementNS = #"select key, item, price, groupid, dateadded from shoppinglist order by dateadded";
const char *queryStatement = [queryStatementNS UTF8String];
dbrc = sqlite3_prepare_v2(db, queryStatement, -1, &dbps, NULL);
//Richiamo la funzione sqlite3_step() finché ho righe nel database
while ((dbrc = sqlite3_step(dbps)) == SQLITE_ROW) {
int primaryKeyValueI = sqlite3_column_int(dbps, 0);
NSNumber *primaryKeyValue = [[NSNumber alloc] initWithInt:primaryKeyValueI];
NSString *itemValue = [[NSString alloc] initWithUTF8String:(char*) sqlite3_column_text(dbps, 1)];
double priceValueD = sqlite3_column_double(dbps, 2);
NSNumber *priceValue = [[NSNumber alloc] initWithDouble:priceValueD];
int groupValueI = sqlite3_column_int(dbps, 3);
NSNumber *groupValue = [[NSNumber alloc] initWithInt:groupValueI];
NSString *dateValueS = [[NSString alloc] initWithUTF8String:(char*) sqlite3_column_text(dbps, 4)];
NSDate *dateValue = [dateFormatter dateFromString: dateValueS];
NSMutableDictionary *rowDict = [[NSMutableDictionary alloc] initWithCapacity:5];
[rowDict setObject:primaryKeyValue forKey: ID_KEY];
[rowDict setObject:itemValue forKey: ITEM_KEY];
[rowDict setObject:priceValue forKey: PRICE_KEY];
[rowDict setObject:groupValue forKey: GROUP_ID_KEY];
[rowDict setObject:dateValue forKey: DATE_ADDED_KEY];
[shoppingListItems addObject: rowDict];
//rilascio tutti gli elementi
[dateValue release];
[primaryKeyValue release];
[itemValue release];
[priceValue release];
[groupValue release];
[rowDict release];
}
}
For the brave who wants to check all the project (there is just another class) here there is the link with all my work. http://www.mediafire.com/?qxfde723r29nhtb
Thanks in advance.
You have too many mistakes in your code. Let's briefly look at them:
1) In your application delegate you place db initialization code in applicationDidFinishLaunching method, but according to Apple's manuals:
This method is used in earlier versions of iOS to initialize the
application and prepare it to run. In iOS 3.0 and later, you should
use the application:didFinishLaunchingWithOptions: instead.
so, I just moved initializeDb method into - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
2) In ListViewController you have a method loadDataFromDb but I didn't find its usage. You never call this method. In the same controller you have viewWillAppear method that I used to initialize your shoppingListItems array that will be shown in tableView as follows:
-(void)viewWillAppear:(BOOL)animated {
shoppingListItems = [[NSMutableArray alloc] init];
[self loadDataFromDb];
[tableView reloadData];
}
tableView is a outlet to UITableView control that you place in your nib file. I added its declaration in ListViewController.h:
#interface ListViewController : UIViewController {
UITableViewCell *nibLoadedCell;
IBOutlet UITableView *tableView;
}
#property(nonatomic, retain) IBOutlet UITableViewCell *nibLoadedCell;
#end
and bind in interface builder with the actual control.
3) AddItemViewController's method addShoppingListItem didn't work because didn't pass this condition:
if (([itemNameField.text length] == 0) || ([priceField.text length] == 0) || ([priceField.text doubleValue] == 0.0)) {
return;
}
You didn't bind your outlets in interface builder for itemNameField, priceField, groupPicker.
By fixing this I got working solution, but actually I didn't check memory usage and suppose you have also some problem in memory management here.
Been running instruments on my app. Its says i am leaking 864bytes & 624bytes from 2 NSCFString and the library responsible is Foundation.
So that leads me to believe thats its not a leak caused by me? Or is it?
Here is the offending method according to instruments. It seems to be a
substringWithRange
that is leaking.
-(void) loadDeckData
{
deckArray =[[NSMutableArray alloc] init];
NSString* path = [[NSBundle mainBundle] pathForResource:#"rugby" ofType:#"txt"
inDirectory:#""];
NSString* data = [NSString stringWithContentsOfFile:path encoding:
NSUTF8StringEncoding error: NULL];
NSString *newString = #"";
NSString *newline = #"\n";
NSString *comma = #",";
int commaCount = 0;
int rangeCount = 0;
NSString *nameHolder = #"";
NSString *infoHolder = #"";
NSMutableArray *statsHolder = [[NSMutableArray alloc] init];
for (int i=0; i<data.length; i++)
{
newString = [data substringWithRange:NSMakeRange(i, 1)];
if ([newString isEqualToString: comma]) //if we find a comma
{
if (commaCount == 0)// if it was the first comma we are parsing the
NAME
{
nameHolder = [data substringWithRange:NSMakeRange(i-
rangeCount, rangeCount)];
}
else if (commaCount == 1)//
{
infoHolder = [data substringWithRange:NSMakeRange(i-
rangeCount, rangeCount)];
//NSLog(infoHolder);
}
else // if we are on to 2nd,3rd,nth comma we are parsing stats
{
NSInteger theValue = [[data
substringWithRange:NSMakeRange(i-rangeCount,rangeCount)]
integerValue];
NSNumber* boxedValue = [NSNumber
numberWithInteger:theValue];
[statsHolder addObject:boxedValue];
}
rangeCount=0;
commaCount++;
}
else if ([newString isEqualToString: newline])
{
NSInteger theValue = [[data substringWithRange:NSMakeRange(i-
rangeCount,rangeCount)] integerValue];
NSNumber* boxedValue = [NSNumber numberWithInteger:theValue];
[statsHolder addObject:boxedValue];
commaCount=0;
rangeCount=0;
Card *myCard = [[Card alloc] init];
myCard.name = nameHolder;
myCard.information = infoHolder;
for (int x = 0; x < [statsHolder count]; x++)
{
[myCard.statsArray addObject:[statsHolder
objectAtIndex:x]];
}
[deckArray addObject:myCard];
[myCard autorelease];
[statsHolder removeAllObjects];
}
else
{
rangeCount++;
}
}
[statsHolder autorelease];
}
Thanks for your advice.
-Code
As Gary's comment suggests this is very difficult to diagnose based on your question.
It's almost certainly a leak caused by you however, I'm afraid.
If you go to the View menu you can open the Extended Detail. This should allow you to view a stack trace of exactly where the leak occurred. This should help diagnose the problem.
When to release deckArray? If deckArray is a class member variable and not nil, should it be released before allocate and initialize memory space?