在这个方法中,我在sqlite数据库中添加了UITextFields,图像和其他字符串的内容。一切正常。我的意思是,当我按下“添加”按钮时,会出现“确定”图像,声音播放和所有内容都会添加到数据库中(我可以检查重启应用程序)。但在所有这些之后,我在“main.m”中出现了这个错误
这是方法:
-(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];
}
修改
感谢Isaac I(也许)发现了这个问题:我没有保留我从相机拍摄的照片。
-(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;
}
现在它有效!但如果你能看到其他问题,请让我注意一下。
答案 0 :(得分:4)
没有理由像这样创建NSString
:
statusLabel.text = [[NSString alloc] initWithFormat: @"Specificare un nome."];
简单写一下
statusLabel.text = @"Specificare un nome.";
也许这不是EXC_BAD_ACCESS
的原因,但至少可以避免几次内存泄漏。
答案 1 :(得分:3)
当您尝试访问已解除分配的内存时,通常会发生EXC_BAD_ACCESS。在您的代码示例中,我没有看到任何[对象释放]调用(这完全是另一个问题,除非您碰巧使用ARC)。但我猜这个错误是在这个方法范围之外进行的调用的结果 - 某些东西正在过早地释放。
您可以粘贴整个班级,或者考虑使用“工具”工具“Zombies”来识别可能导致此问题的悬挂指针。
答案 2 :(得分:0)
在我看来isaac是对的。我只想添加一个猜测。调用
时,最有可能发生错误[[self parentViewController]dismissModalViewControllerAnimated:YES];
到目前为止,我认为,你在parentViewController中已经发布了一些内容,所以当你试图将它显示回来时,程序会转向已发布的变量并让你崩溃。
只需借助断点即可轻松检测到它。