IOS Potential Leak an Object Message - ios

I am developing an IOS application. I am fully understand the logic of the memory management. I did analyze with Xcode instruments then I saw "Potential leak an object" message. What is wrong with the code below. Can you help me please ?
-(CountriesDTO*)getNationalityCountry{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *userNationality = (([def stringForKey:#"passCitizenshipCountry"]!=nil && [def stringForKey:#"passCitizenshipCountry"]!=NULL)?[def stringForKey:#"passCitizenshipCountry"]:#"");
CountriesDTO *ct = [self getCountryForCode:userNationality];
return ct; **//Potential leak of an object**
}
-(CountriesDTO*)getUserPhoneCodeCountry{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *userPhoneCode = (([def stringForKey:#"countryPhoneFlagCode"]!=nil && [def stringForKey:#"countryPhoneFlagCode"]!=NULL)?[def stringForKey:#"countryPhoneFlagCode"]:#"");
CountriesDTO *ct = [self getCountryForCode:userPhoneCode];
return ct; **//Potential leak of an object**
}
-(CountriesDTO*)getCountryForCode:(NSString*)candidateCode{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *userSiteCountry = (([def stringForKey:#"userSiteUrlCountry"]!=nil && [def stringForKey:#"userSiteUrlCountry"]!=NULL)?[def stringForKey:#"userSiteUrlCountry"]:#"");
NSString *defCode = #"";
if (![candidateCode isEqualToString:#""]) {
//Kullanıcının profilindeki nationality veya phone code dolu ise bu kullanılır.
defCode = candidateCode;
}else{
defCode=#"TR";
}
DatabaseController *db = [[[DatabaseController alloc] init] autorelease];
CountriesDTO *ct = [db getCountry:defCode];
if (ct==nil) {
ct = [[CountriesDTO alloc] init];
ct.countryCode_=#"";
ct.countryId_=#"";
ct.countryName_=#"";
ct.countryPhoneCode_=#"";
}
return ct; **//Potential leak of an object**
}
-(CountriesDTO*)getCountry:(NSString*)countryCode{
CountriesDTO *model=[[[CountriesDTO alloc] init] autorelease];
if (![db open]) {
[db release];
}else{
FMResultSet *s = [db executeQuery:[NSString stringWithFormat:#"SELECT * FROM country Where code ='%#'",countryCode]];
while ([s next]) {
//retrieve values for each record
[model setCountryId_:[s stringForColumn:#"id"]];
[model setCountryCode_:[s stringForColumn:#"code"]];
[model setCountryPhoneCode_:[s stringForColumn:#"phoneCode"]];
[model setCountryName_:[s stringForColumn:#"name"]];
}
[db close];
}
return model;
}

You are allocating ct and never releasing it:
ct = [[CountriesDTO alloc] init];
Use autorelease there:
ct = [[[CountriesDTO alloc] init] autorelease];

Related

Saving and restoring NSMutablearray to NSUserdefaults

I am writing a app that needs to save and restore nsmutablearrays to populate a table view. The array will save but won't overwrite once i reset everything. i find that the values are combining together and is giving me unreliable averages... code is below. also i have various view controllers that have this lap function...
// code that adds items to table view and saves a version of the array to nsmutablearray
NSUserDefaults *prefs = [[NSUserDefaults alloc]
initWithSuiteName:#"group.com.DJ.TSTML"];
[tableItems3 insertObject:TimeString2 atIndex:0];
// time string is the time as a nsstring
[tableItems4 addObject:[NSNumber numberWithFloat:seconds2]];
[tableview reloadData];
[prefs setObject:self.tableItems4 forKey:#"SavedArray3"];
[prefs setObject:self.tableItems3 forKey:#"SavedArray4"];
// this is saving to insurer defaults
NSString *newString = [NSString stringWithFormat:#"%lu", (unsigned long)tableItems3.count];
[Commentcount setText:newString];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSNumber *average = [tableItems4 valueForKeyPath:#"#avg.self"];
Average.text = [formatter stringFromNumber:average];
NSLog(#"Sucess");
[prefs synchronize];
} }
Restoring the array :
NSUserDefaults *prefs = [[NSUserDefaults alloc]
initWithSuiteName:#"group.com.DJ.TSTML"];
// code used to erase current values in the table view and restore from NSUserDefaults
tableItems3 = [[NSMutableArray alloc] init];
tableItems4 = [[NSMutableArray alloc] init];
[tableview reloadData];
NSMutableArray *RestoreArray1 = [[prefs objectForKey:#"SavedArray4"]mutableCopy];
NSMutableArray *RestoreArray2 = [[prefs objectForKey:#"SavedArray3"]mutableCopy];
[tableItems3 addObjectsFromArray:RestoreArray1];
[tableItems4 addObjectsFromArray:RestoreArray2];
if (tableItems3 == nil) {
tableItems3 = [[NSMutableArray alloc] init];
tableItems4 = [[NSMutableArray alloc] init];
}
[tableview reloadData];
NSLog(#"%#",tableItems4);
}
}
Thank you in advance for any help!
My issue to be clear is that every time i save to nsuserdefaults instead of overwriting the previous array it just keeps the old array and combines with the new one
Ok so i answered my own question. As someone brought up it was combining because i was retrieving without overwriting it first. the following code is what worked...
NSString *Clearstring = [prefs objectForKey:#"Clear?"];
// i created a nsstring that when the method for restarting would change accordingly.
// so when someone would navigate to this view controller this would fire.
// if clear is yes i would prevent the code that controled the restore function from restoring and prepare
// it if it was needed to be restored again.
if ([Clearstring isEqualToString:#"Yes"]) {
tableItems3 = [[NSMutableArray alloc] init];
tableItems4 = [[NSMutableArray alloc] init];
[prefs setObject:self.tableItems4 forKey:#"SavedArray3"];
[prefs setObject:self.tableItems3 forKey:#"SavedArray4"];
[prefs setObject:#"NO" forKey:#"Clear?"];
[tableview reloadData];
}
else{
tableItems3 = [[NSMutableArray alloc] init];
tableItems4 = [[NSMutableArray alloc] init];
[tableview reloadData];
NSMutableArray *RestoreArray1 = [[prefs objectForKey:#"SavedArray4"]mutableCopy];
NSMutableArray *RestoreArray2 = [[prefs objectForKey:#"SavedArray3"]mutableCopy];
[tableItems3 removeAllObjects];
[tableItems4 removeAllObjects];
[tableItems3 addObjectsFromArray:RestoreArray1];
[tableItems4 addObjectsFromArray:RestoreArray2];
if (tableItems3 == nil) {
tableItems3 = [[NSMutableArray alloc] init];
tableItems4 = [[NSMutableArray alloc] init];
}
[tableview reloadData];
NSLog(#"%#",tableItems4);
}
}

Why my array of NSDictionary lost its objects?

I'm having a difficulty with this one I have a method that returns a value of Array of NSDictionary once I pass the return value of an array first it works. I already get the object in my NSLog but when I try to access the objects of my Array of NSDictionary in another method I get the error and I think that I loses the objects of the array.
Here's the method that return an Array of NSDictionary:
-(NSMutableArray *)selectItemDataTbl {
NSMutableArray *l_array_data = [[NSMutableArray alloc] init];
NSString *query = #"SELECT pid, fname, gen_name, type, fu, fprice FROM tbl_selectItem_data";
sqlite3_stmt *l_statement;
if (sqlite3_open([l_SqliteDb UTF8String], &(_database)) == SQLITE_OK) {
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &l_statement, nil) == SQLITE_OK) {
while(sqlite3_step(l_statement) == SQLITE_ROW){
NSMutableDictionary *l_dataDictionary = [[NSMutableDictionary alloc]init];
NSString *l_pid = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 0)];
NSString *l_name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 1)];
NSString *l_genName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 2)];
NSString *l_Type = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 3)];
NSString *l_u = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 4)];
NSString *l_Price = [NSString stringWithUTF8String:(char *)sqlite3_column_text(l_statement, 5)];
[l_dataDictionary setObject:l_pid forKey:#"pid"];
[l_dataDictionary setObject:l_name forKey:#"name"];
[l_dataDictionary setObject:l_genName forKey:#"genName"];
[l_dataDictionary setObject:l_Type forKey:#"Type"];
[l_dataDictionary setObject:l_u forKey:#"u"];
[l_dataDictionary setObject:l_Price forKey:#"Price"];
[l_array_data addObject:l_dataDictionary];
}
NSLog(#"l_array_data count: %i", [l_array_data count]);
sqlite3_finalize(l_statement);
sqlite3_close(_database);
}
}
return l_array_data;
}
And here my method how I access it I'm calling it on my viewDidLoad:
- (void)selectItemData {
_l_alldataInSelectItem = [[NSMutableArray alloc] init];
_l_prodId = [[NSMutableArray alloc] init];
_l_prodName = [[NSMutableArray alloc] init];
_l_prodGenName = [[NSMutableArray alloc] init];
_l_prodCompType = [[NSMutableArray alloc] init];
_l_prodUom = [[NSMutableArray alloc] init];
_l_prodListPrice = [[NSMutableArray alloc] init];
_l_alldataInSelectItem = [dbc selectItemDataTbl];
_l_selectItemData_Dictionary = [[NSDictionary alloc] init];
for (_l_selectItemData_Dictionary in _l_alldataInSelectItem) {
NSString *Id = [_l_selectItemData_Dictionary valueForKey:#"pid"] ;
NSString *Name = [_l_selectItemData_Dictionary valueForKey:#"name"];
NSString *GenName = [_l_selectItemData_Dictionary valueForKey:#"genName"];
NSString *Type = [_l_selectItemData_Dictionary valueForKey:#"Type"];
NSString *U = [_l_selectItemData_Dictionary valueForKey:#"u"];
NSString *Price = [_l_selectItemData_Dictionary valueForKey:#"Price"];
[_l_prodId addObject:Id];
[_l_prodName addObject:Name];
[_l_prodGenName addObject:GenName];
[_l_prodCompType addObject:GenName];
[_l_prodUom addObject:U];
[_l_prodListPrice addObject:Price];
}
NSLog(#"adsfasdf %#", _l_prodId);
NSLog(#"adsfasdf %i", [_l_alldataInSelectItem count]);
}
But in this method I can't get the value of my array _l_alldataInSelectItem
- (void)textFieldshouldChange {
NSString *searchKey = self.txt_SearchField.text;
NSMutableArray *searchingData = [[NSMutableArray alloc] init];
if (![searchKey isEqualToString:#""]) {
NSLog(#"When TextField text is changed, this will be called");
NSLog(#"textFieldshouldChange _l_alldataInSelectItem: %i", [_l_alldataInSelectItem count]);
}
}
here's how i declare my l_alldataInSelectItem. I declared it on my header file
#property (strong, nonatomic) NSMutableArray *l_alldataInSelectItem, *l_prodId, *l_prodName, *l_prodGenName, *l_prodCompType, *l_prodUom, *l_prodListPrice;
Go systematically through the possibilities.
Possibility 1: There are gremlins somewhere trying to annoy you. We exclude that.
Possibility 2: You never created the data. Set a breakpoint on the return statement in selectItemDataTbl and check it.
Possibility 3: You never stored the array. Well, there is the fact that you store an empty mutable array into _l_alldataInSelectItem which is absolutely pointless, but set a breakpoint on the last statement in selectItemData and check it.
Possibility 4: You stored it and overwrote it. Search for all places where you store to _l_alldataInSelectItem or to a property named l_alldataInSelectItem, set breakpoints everywhere, and check.
Possibility 5 (the stupid one): _l_alldataInSelectItem is a weak instance variable or a weak property.
Possibility 6: You stored it, but looked for it in a different place. Is the self in textFieldshouldChange the same as the self in selectItemData? Set breakpoints and check.
Possibility 7: You are doing something asynchronously. The variable will be set, but much later than you think.
Most important: Put it very strongly in your mind that you did something wrong, and you don't have to solve any magical puzzles, all you need to do is find out what you did wrong.

ios App crash instantly after in-app purchase buying

Basically, i am in really bad situation. Our team successfully develop and release new version of application with new feature, which users are able to buy (in-app purchases).
So, we have tested all new functionality with iTunes test user, and everything worked great, however, when we saw release version in appStore with real iTunes user, there is a huge problem. User just press button to buy in-app purchase, after he write password of his account and accept to buy this new information. Unfortunately, app crashes everytime after this action. And there is no actions after this.
Basically, for in-app purchases I use MKStoreKit.
So, I would like to present code of the following action:
- (IBAction)buyNewRequest:(id)sender
{
id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
[tracker send:[[GAIDictionaryBuilder createEventWithCategory:#"uiAction"
action:#"Обработчик нажатия кнопки"
label:#"Кнопка - отправить запрос. Экран - запроса кредитной истории бки"
value:[NSNumber numberWithInt:100]] build]];
if ([self checkValidaionTextFields])
{
[DejalBezelActivityView activityViewForView:self.view withLabel:#"Подождите..."].showNetworkActivityIndicator = YES;
self.sendButton.enabled = NO;
[[MKStoreManager sharedManager] buyFeature:#"ru.financemart.nbki"
onComplete:^(NSString* purchasedFeature,
NSData* purchasedReceipt,
NSArray* availableDownloads)
{
id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
[tracker send:[[GAIDictionaryBuilder createEventWithCategory:#"uiAction"
action:#"Уведомление подтверждения покупки БКИ"
label:#"Уведомление - покупка бки. Экран - отправки запроса кредитной истории БКИ"
value:[NSNumber numberWithInt:100]] build]];
NSString *stringReceipt = [NSString stringWithFormat:#"%#", purchasedReceipt];
stringReceipt = [stringReceipt stringByReplacingOccurrencesOfString:#" " withString:#""];
stringReceipt = [stringReceipt stringByReplacingOccurrencesOfString:#"<" withString:#""];
stringReceipt = [stringReceipt stringByReplacingOccurrencesOfString:#">" withString:#""];
NSString *base64Receipt = [self base64forData:purchasedReceipt];
NSString *hashDevelopKey = #"i5FnXIZ2aKjdn1Ru2VfLarbdCwbiJvfsnh9QTm9MB0I";
NSString *hashMD5 = #"";
hashMD5 = [hashMD5 stringByAppendingString:hashDevelopKey];
NSString *familyText = self.familyTextField.text;
NSString *nameText = self.nameTextField.text;
NSString *patronimicText = self.patronimicTextField.text;
NSString *passportID = self.passportID.text;
NSString *email = self.emailTextField.text;
NSString *dateOfBirth = dateOfBirthFormat;
NSString *passportDate = datePassportFormat;
NSString *regionForRequest = #"";
if ([[UnicomAPIConfigResponse lastResponse] cityByID:#(self.unicomProposalsModel.cityID).stringValue].ru_RU != nil) {
regionForRequest = [[UnicomAPIConfigResponse lastResponse] cityByID:#(self.unicomProposalsModel.cityID).stringValue].ru_RU;
}
hashMD5 = [hashMD5 stringByAppendingString:dateOfBirth];
hashMD5 = [hashMD5 stringByAppendingString:email];
hashMD5 = [hashMD5 stringByAppendingString:nameText];
hashMD5 = [hashMD5 stringByAppendingString:patronimicText];
hashMD5 = [hashMD5 stringByAppendingString:passportID];
hashMD5 = [hashMD5 stringByAppendingString:passportDate];
hashMD5 = [hashMD5 stringByAppendingString:base64Receipt];
hashMD5 = [hashMD5 stringByAppendingString:regionForRequest];
hashMD5 = [hashMD5 stringByAppendingString:familyText];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *stringToken = [[[[defaults valueForKey:#"deviceToken"] description]
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]]
stringByReplacingOccurrencesOfString:#" "
withString:#""];
hashMD5 = [hashMD5 stringByAppendingString:stringToken];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd.MM.yyyy"];
NSString *stringFromDate = [formatter stringFromDate:[NSDate date]];
hashMD5 = [hashMD5 stringByAppendingString:stringFromDate];
[DejalBezelActivityView activityViewForView:self.view withLabel:#"Отправляем..."].showNetworkActivityIndicator = YES;
[self.unicomService postNBKIRequestWithName:nameText WithFamily:familyText andPatronimic:patronimicText andDOB:dateOfBirth andPassport:passportID andPassportDate:passportDate andPartnerName:#"1" andEmail:email andToken:stringToken andReceipt:base64Receipt andHashKey:[self md5:hashMD5] andRegion:regionForRequest success:^(UnicomAPIRequestsNBKIResponse *response)
{
self.sendButton.enabled = YES;
} error:^(NSError *error) {
self.sendButton.enabled = YES;
[self performSelector:#selector(showError) withObject:nil afterDelay:2.0];
}]->addObserver( ^( TLSignal<NSDictionary *> *sender, NSDictionary *response )
{
[self performSelector:#selector(showSuccessPostRequest) withObject:nil afterDelay:0.0];
userModel = [CreditUserModel tlSharedInstance];
NSDictionary *dicta = [userModel.serverResponse valueForKey:#"result"];
NSString *dictb = [dicta valueForKey:#"id"];
NSMutableDictionary *paramNBKI = [[NSMutableDictionary alloc] init];
[paramNBKI setObject:dictb forKey:#"requestID"];
[paramNBKI setObject:self.familyTextField.text forKey:#"familyName"];
[paramNBKI setObject:self.nameTextField.text forKey:#"name"];
[paramNBKI setObject:self.patronimicTextField.text forKey:#"patronimic"];
[paramNBKI setObject:passportID forKey:#"passportID"];
[paramNBKI setObject:dateOfBirth forKey:#"dateOfBirth"];
[paramNBKI setObject:passportDate forKey:#"passportDate"];
[paramNBKI setObject:base64Receipt forKey:#"baseReceipt"];
[paramNBKI setObject:[self convertDate:[NSDate date]] forKey:#"requestDate"];
NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
if([[[defaults dictionaryRepresentation] allKeys] containsObject:#"nbkiHistory"])
{
NSMutableArray *nbkiHistory = [[NSMutableArray alloc] init];
nbkiHistory = [NSMutableArray arrayWithArray:[defaults valueForKey:#"nbkiHistory"]];
[nbkiHistory addObject:paramNBKI];
[defaults setObject:nbkiHistory forKey:#"nbkiHistory"];
NSLog(#"mykey found");
} else {
NSMutableArray *nbkiHistory = [[NSMutableArray alloc] init];
[nbkiHistory addObject:paramNBKI];
[defaults setObject:nbkiHistory forKey:#"nbkiHistory"];
}
self.sendButton.enabled = YES;
} );
}
onCancelled:^
{
self.sendButton.enabled = YES;
[DejalBezelActivityView removeViewAnimated:YES];
}];
}
}
So, after user accept in-app purchase you could see POST request to our server ([self.unicomService postNBKIRequestWithName:), but there are no requests in our server database log, so app crashes before this code. But, there are no code strings where are it is able to crash.

Same object saved to NSUserDefaults over and over again when the NSMutableDictionary is different

It's driving me crazy, I did a log and I see the objects are different, but when I get then back from NSUserDefaults, all of the objects are the same.
My code:
- (void)breakTrapsToSave:(NSDictionary*)trapsDict firstTimeUpdate:(Boolean)firstTimeUpdate
{
// If traps already save
// we will get them from NSUserDefaults
// and then update them
if (!firstTimeUpdate)
{
allTraps = [self.sharedPrefs objectForKey:#"arrayOfAllTraps"];
}
// JSON Parsing
tempA = trapsDict[#"Envelope"];
tempB = tempA[#"Body"];
tempC = tempB[#"getTrapsResponse"];
tempD = tempC[#"getTrapsResult"];
tempE = tempD[#"TRAPS"];
self.lastUpdate = tempE[#"lastUpdate"];
[[NSUserDefaults standardUserDefaults] setObject:self.lastUpdate forKey:#"last_update"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Traps latest updated at: %#", self.lastUpdate);
tempF = tempE[#"TRAP"];
if (tempF.count <= 0)
{
newTrapsUpdates = false;
NSLog(#"NO NEW TRAPS!");
}
else
{
newTrapsUpdates = true;
NSLog(#"NEW TRAPS FOUND");
[tempF enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
tempA = tempF[idx];
NSString *finalResult;
NSString *key;
NSMutableDictionary *singleTrap = [[NSMutableDictionary alloc] init];
for (int i=0; i < node.count; i++)
{
finalResult = tempA[node[i]];
key = node[i];
if ([finalResult length] <= 0)
{
finalResult = #"0";
}
singleTrap[key] = finalResult;
}
if (allTraps.count <= 0)
{
allTraps = [[NSMutableArray alloc] initWithObjects:singleTrap, nil];
}
else
{
[allTraps addObject:singleTrap];
}
counter = idx;
}];
allTraps = [[IDANNetroads sharedInstance] removeDuplicatedFromArray:allTraps];
// Save all traps
[[NSUserDefaults standardUserDefaults] setObject:allTraps forKey:#"arrayOfAllTraps"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Total Traps: %d", allTraps.count);
NSLog(#"Total New Traps: %d", counter);
}
}
I did a log and I see allTraps[idx] = singleTrap; is different as it should be, but when I print the log for NSLog(#"allTraps: %#", allTraps); I see all of the objects are the last object.
EDIT:
Eventually, I replaced the singleTrap allocation and now it's inside the enumeration block:
NSMutableDictionary *singleTrap = [[NSMutableDictionary alloc] init];
And I added this code:
if (allTraps.count <= 0)
{
allTraps = [[NSMutableArray alloc] initWithObjects:singleTrap, nil];
}
else
{
[allTraps addObject:singleTrap];
}
So, the final code is edited.
Whatever singleTrap is, you're repeatedly mutating it and storing another reference to the same object in your allTraps array. You need to create (instantiate) a new item for each entry you want in your allTraps list.
It looks like singleTrap is an array of strings, so try:
allTraps[idx] = [singleTrap copy];

Singleton in static library in iOS

I have a static library which contains a Singleton class (FMDB SQLite Data Access), now I open from my main application the connection and do thingss... this works, after that a method in my library want to call the a method on my singleton and I get the error that
-[FMDatabase executeQuery:withArgumentsInArray:]: message sent to deallocated instance 0xa443960
is this not possible what I'm trying to achieve?
this is short version of my singleton
static MySingleton* _sharedMySingleton = nil;
FMDatabase *database;
#ifndef __clang_analyzer__
+(MySingleton*)sharedMySingleton
{
#synchronized([MySingleton class])
{
if (!_sharedMySingleton)
[[self alloc] init];
return _sharedMySingleton;
}
}
#endif
+(id)alloc
{
#synchronized([MySingleton class])
{
NSAssert(_sharedMySingleton == nil, #"Attempted to allocate a second instance of a singleton.");
_sharedMySingleton = [super alloc];
return _sharedMySingleton;
}
}
-(Resource *)getResourceForName:(NSString *)name
{
NSString *select = #"SELECT Data, MimeType FROM File WHERE FileName = ? LIMIT 1";
NSArray *arguments = [NSArray arrayWithObject:[NSString stringWithFormat:#"/%#", name]];
FMResultSet *s = [database executeQuery:select withArgumentsInArray:arguments];
if (s == NULL)
{
FuncFileLog(#"getResourceForName file cant be loaded: %#", [database lastErrorMessage]);
return nil;
}
NSData *data = nil;
NSString *mimeType;
while ([s next])
{
data = [NSData dataFromBase64String:[s stringForColumnIndex:0]];
mimeType = [s stringForColumnIndex:1];
}
Resource *resource = [[[Resource alloc] initWithData:data mimeType:mimeType] autorelease];
return resource;
}
-(BOOL)openDatabase
{
database = [FMDatabase databaseWithPath:[self getDocumentResourcePath]];
return [database open];
}
-(void)closeDatabase
{
[database close];
[database release];
}
-(void)dealloc
{
if (database != NULL)
{
[self closeDatabase];
}
[baseUrl release];
[super dealloc];
}
#end
EDIT:
I found that the dealloc from FMDatabase gets called after my application start return, but dont know why.
EDIT2:
Currently I thought one problem was this line
database = [FMDatabase databaseWithPath:[self getDocumentResourcePath]];
here I have to retain the object.
You don't actually assign the singleton instance:
if (!_sharedMySingleton)
[[self alloc] init];
should be:
if (!_sharedMySingleton)
_sharedMySingleton = [[self alloc] init];
and dump that overridden alloc method.
Also database should be an instance variable in the class, and not at global scope.

Resources