Early dealloc call over-releasing object iOS - ios

My app is crashing due to an over-released object and I have narrowed it down to the early call of dealloc in a custom class. This causes a crash attributed to an NSMutableArray that is using the custom class listed below:
#import <Foundation/Foundation.h>
#interface GraphData : NSObject{
NSInteger key;
NSString *value;
}
#property (nonatomic, readwrite) NSInteger key;
#property (nonatomic, retain) NSString *value;
-(id)initWithPrimaryKey:(NSInteger) xid;
-(id)initWithName:(NSString *)n key:(NSInteger)i;
#end
#import "GraphData.h"
#implementation GraphData
#synthesize key,value;
-(id)initWithPrimaryKey:(NSInteger) xid{
//[super init];
self=[super init];
if (self){
self.key = xid;
self.value = #"";
}
return self;
}
-(id)initWithName:(NSString *)n key:(NSInteger)i{
self=[super init];
if (self){
self.key = 0;
self.value = n;
}
return self;
}
-(void)dealloc{
NSLog(#"Say bye to %#, kids!", self);
[value release], value = nil;
[super dealloc];
}
#end
Weirdly I'm using GraphData in another class and it works without a problem. In this case however the dealloc calls just before I synthesise the NSMutableArray theNewData property; but after I have synthesised it three times.
-(NSMutableArray*)fillDataInArray:(NSInteger)keyphrase_id{
NSLog(#"lsd");
NSLog(#"Keyphrase_id:%d", keyphrase_id);
NSDate *startdate = [self getDateForApplicationInstalled];
NSDate *enddate = [NSDate date];
NSString *dateString1=[[NSString alloc] initWithString: [fmt stringFromDate:startdate]];
NSString *dateString2=[[NSString alloc] initWithString: [fmt stringFromDate:enddate]];
NSMutableArray *newDataNew = [[NSMutableArray alloc]init];
self.theNewData = newDataNew;
[newDataNew release];
selStmt = nil;
// build select statement
if (!selStmt)
{
const char *sql = "select distinct position, key_time from ranking where keyphrase_id = ? and key_time between ? and ? order by key_time";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
NSInteger n = keyphrase_id;
sqlite3_bind_int(selStmt, 1, n);
sqlite3_bind_text(selStmt, 2, [dateString1 UTF8String] , -1, SQLITE_TRANSIENT);
sqlite3_bind_text(selStmt, 3, [dateString2 UTF8String] , -1, SQLITE_TRANSIENT);
NSLog(#"SQL query is: [%s]", sql);
}
if (!selStmt)
{
NSAssert1(0, #"Can't build SQL to read keyphrases [%s]", sqlite3_errmsg(database));
}
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{
GraphData *item = [[GraphData alloc]init];
item.key = sqlite3_column_int(selStmt, 0);
item.value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selStmt,1)];
[self.theNewData addObject:item];
[item release];
}
sqlite3_reset(selStmt); // reset (unbind) statement
[dateString2 release];
[dateString1 release];
return theNewData;
}
It's also accessed in a different method:
-(NSMutableArray *) getDataForCharts:(int)seriesIndex{
NSLog(#"speed");
NSDate *startdate = [self getDateForApplicationInstalled];
NSDate *enddate = [NSDate date];
NSString *dateString1=[[NSString alloc] initWithString: [fmt stringFromDate:startdate]];
NSString *dateString2=[[NSString alloc] initWithString: [fmt stringFromDate:enddate]];
NSMutableArray *newDataNew = [[NSMutableArray alloc]init];
self.actionNoteData = newDataNew;
[newDataNew release];
selStmt = nil;
// build select statement
if (!selStmt)
{
const char *sql = "";
if (seriesIndex == 4) sql = "select distinct 105 score, notes_date from notes where iscompleted =1 and domain_id = ? and notes_date between ? and ? order by notes_date";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
NSInteger n = domain_id;
sqlite3_bind_int(selStmt, 1, n);
sqlite3_bind_text(selStmt, 2, [dateString1 UTF8String] , -1, SQLITE_TRANSIENT);
sqlite3_bind_text(selStmt, 3, [dateString2 UTF8String] , -1, SQLITE_TRANSIENT);
NSLog(#"SQL query is: [%s]", sql);
}
if (!selStmt)
{
NSAssert1(0, #"Can't build SQL to read keyphrases [%s]", sqlite3_errmsg(database));
}
// loop reading items from list
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{
GraphData *item = [[GraphData alloc]init]; // create item
item.key = sqlite3_column_int(selStmt, 0);
item.value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selStmt,1)];
NSLog(#"Key:%d", sqlite3_column_int(selStmt, 0));
NSLog(#"Value:%s", sqlite3_column_text(selStmt,1));
[self.actionNoteData addObject:item]; // add to list
[item release]; // free item
}
sqlite3_reset(selStmt); // reset (unbind) statement
[dateString2 release];
[dateString1 release];
return actionNoteData;
}
Zombie points to [i release]; but this is the exact statement called earlier which doesn't result in a crash.
if (index == 4) {
dateComponents.day = ([dateComponents day] -1 ) + dataindex + 1;
if (dataForPlotActionNote.count > dataindex) {
if ([dataForPlotActionNote objectAtIndex:dataindex]) {
GraphData *i = (GraphData *) [dataForPlotActionNote objectAtIndex:dataindex];
NSDate *date = [[[NSDate alloc] init] autorelease];
date =[fmt dateFromString:i.value];
datapoint.xValue = date;//[cal dateFromComponents:dateComponents];
datapoint.yValue = [NSNumber numberWithDouble:(i.key)];
[i release];
}
}
}
What could cause the dealloc call to occur halfway through the executing code?
Could making a GraphData property and reseting it each time help keep it alive long enough?

The [i release] problem makes sense. When you get a reference to the object that's inside dataForPlotActionNote you don't increase its retain count, so you shouldn't be reducing the count either.
The places where you use [item release] are different in that you've created those objects with alloc and therefore do have them retained.

Related

iOS: Tracking amount of allocated objects

We can use instruments for various kinds of analysis. But many programmers find this tool to be too complicated and too heavy to bring real value.
Is there a simple way to track all objects of a specific class, and for each to know who exactly was allocating them and to verify that they are being freed correctly?
The answer is yes! there is a way, and I'll demo it in my answer below
Tracking allocations easily:
How to use: you can put the 150 lines of code below into a file named AllocTracker.m and drag it into your project files.
Use the check box at the right pane of Xcode to enable/disable it in your compilation target.
What you'll get?
when enabled, this module will track all allocations and deallocations of UIImage objects and log them. (It can easily be modified for tracking other classes.)
In addition to logging every allocation and deallocation, it will periodically (currently every 15 seconds) dump all objects which are currently allocated, with some added info and the call stack which allocated them.
What is the added value?
This code was used in big projects to get rid of orphan objects which were left allocated without notice, allowing to significantly reduce the memory footprint of the app and fix memory leaks.
So here is the code for AllocTracker.m:
#define TRACK_ALLOCATIONS
#ifdef TRACK_ALLOCATIONS
#import <UIKit/UIKit.h>
#define TIMER_INTERVAL 15
#implementation UIApplication(utils)
+(NSString *)dateToTimestamp:(NSDate *)date
{
if (date == nil) {
date = [NSDate date];
}
static NSDateFormatter *dateFormatter = nil;
if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setDateFormat:#"HH:mm:ss.S"];
}
NSString *ts = [dateFormatter stringFromDate:date];
return ts;
}
+(NSString*) getCaller:(int)stackDepth
{
#ifndef DEBUG
return #"NON DBG";
#else
NSArray *symbols = [NSThread callStackSymbols];
int lastIndex = (int)(symbols.count - 1);
if (lastIndex < 3) {
return #"NO DATA";
}
NSMutableString *result = [NSMutableString string];
int foundCount = 0;
for (int ix=3; ix <= lastIndex; ix++) {
NSString *line = symbols[ix];
NSRange rng1 = [line rangeOfString:#"["];
if (rng1.location == NSNotFound) {
continue;
}
NSRange rng2 = [line rangeOfString:#"]"];
NSString *caller = [line substringWithRange:NSMakeRange(rng1.location+1, rng2.location-rng1.location-1)];
if (foundCount > 0) { //not first
[result appendString:#"<--"];
}
[result appendString:caller];
if (++foundCount == stackDepth) {
break;
}
}
return (foundCount > 0) ? result : #"NO SYMBOL";
#endif
}
#end
#implementation UIImage(memoryTrack)
static NSMapTable *g_allocsMap;
static NSTimer *g_tmr;
static NSDate *g_lastDump = nil;
+(void)gotTimer:(NSTimer *)timer
{
[self dumpAllocs];
}
+(void)startTimer
{
static int count = 0;
g_tmr = [NSTimer scheduledTimerWithTimeInterval:15 target:self selector:#selector(gotTimer:) userInfo:#(count++) repeats:YES];
NSLog(#"starting timer %i", count);
}
+(void)cancelTimer
{
[g_tmr invalidate];
g_tmr = nil;
}
+(void)dumpAllocs
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
NSMutableString *str = [NSMutableString string];
[str appendString:#"\n#$# ========== Non-freed UIImages =========\n"];
NSMutableArray *sorted = [NSMutableArray array];
//make sure map is not changed while enumerating
static int s_ts_start = -1;
#synchronized (g_allocsMap) {
NSEnumerator *keysEnum = [g_allocsMap keyEnumerator];
UIImage *img;
while (img = [keysEnum nextObject]) {
NSString *value = [g_allocsMap objectForKey:img];
if (value) { //might be nulled because declared as weak
NSUInteger memUsed = CGImageGetHeight(img.CGImage) * CGImageGetBytesPerRow(img.CGImage);
NSString *objData = [NSString stringWithFormat:#"mem=%5ikb, size=%4ix%-4i", (int)(memUsed/1024), (int)img.size.width, (int)img.size.height];
NSString *line = [NSString stringWithFormat:#"%p - %# [%#]\n", img, objData, value];
if (s_ts_start<0) {
s_ts_start = (int)[line rangeOfString:#"["].location + 1;
}
if (line.length > (s_ts_start+10)) {
[sorted addObject:line];
}
}
}
}
if (sorted.count > 0) {
[sorted sortUsingComparator: ^NSComparisonResult(NSString *s1, NSString *s2)
{
//we expect '0x15a973700 - mem=3600kb, size=640x360 [16:14:27.5: UIIma...'
NSString *ts1 = [s1 substringWithRange:NSMakeRange(s_ts_start, 10)];
NSString *ts2 = [s2 substringWithRange:NSMakeRange(s_ts_start, 10)];
return [ts1 compare:ts2];
}];
int ix = 0;
for (NSString *line in sorted) {
[str appendFormat:#"#$# %3i) %#", ix++, line];
}
}
[str appendString:#"#$# ======================================================\n"];
NSLog(#"%#", str);
});
}
+(instancetype)alloc
{
NSString *caller = [UIApplication getCaller:4];
#synchronized (self) {
id obj = [super alloc];
NSLog(#"#$# UIImage alloc: [%p], caller=[%#]", obj, caller);
NSDate *now = [NSDate date];
NSString *value = [NSString stringWithFormat:#"%#: %#", [UIApplication dateToTimestamp:now], caller];
if (!g_allocsMap) {
g_allocsMap = [NSMapTable mapTableWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory];
}
[g_allocsMap setObject:value forKey:obj];
if (!g_lastDump) {
[self startTimer];
g_lastDump = now;
}
return obj;
}
}
-(void)dealloc
{
NSLog(#"#$# UIImage dealloc: [%#]", self);
}
#end
#endif //TRACK_ALLOCATIONS
How it works?
We create a category of UIImage and set our own version for alloc and dealloc. Every allocated object is saved into an NSMapTable object which works like a dictionary but allow storing object with weak pointers.
For convenience we were adding two methods under UIApplication which can be used by other modules if an appropriate header file is created. One method is for formatting the timestamp, and the other is for reading the call stack (only works in debug builds).
Tip for use:
if you use a real device and install idevicesyslog (brew install libimobiledevice), you can use the terminal to see all allocation debug, like this:
idevicesyslog | grep "#\$#"

ios custom class Init not working

I am a beginner to iOS. I am trying to access/read the sqlite DB from within my App and for which I used a model class where I initialize a custom initializer. Values are getting successfully in custom initializers but my issue is that the values are not populating in modal class object.
Here is the code which I implement:
// ViewController.m
{
[self thehadithList];
sqlite3 *database;
NSString *databasePath;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:#"hadithQudsi.db"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select * from hadith";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
NSInteger aID = sqlite3_column_int (compiledStatement, 0);
NSString *aHA = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aHE = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aRA = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString *aRE = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
NSInteger aF = sqlite3_column_int (compiledStatement, 5);
Hadith *hadith1 = [[Hadith alloc] initWithId:aID hadith_ar:aHA hadith_en:aHE ref_ar:aRA ref_en:aRE favourites:aF];
[thehadithList addObject:hadith1]; **// **** Here in Custom class object, values are not been getting **** //**
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
// Hadith.h (this is Modal Class)
#property (nonatomic,readwrite) NSInteger _id;
#property (nonatomic,strong) NSString *hadith_ar;
#property (nonatomic,strong) NSString *hadith_en;
#property (nonatomic,strong) NSString *ref_ar;
#property (nonatomic,strong) NSString *ref_en;
#property (nonatomic,readwrite) NSInteger favourites;
-(id)initWithId:(NSInteger)ID hadith_ar:(NSString *)ha hadith_en:(NSString *)he ref_ar:(NSString *)ra ref_en:(NSString *)re favourites:(NSInteger)f;
// Hadith.m
#synthesize _id,hadith_ar,hadith_en,ref_ar,ref_en,favourites;
-(id)initWithId:(NSInteger)ID hadith_ar:(NSString *)ha hadith_en:(NSString *)he ref_ar:(NSString *)ra ref_en:(NSString *)re favourites:(NSInteger )f
{
if (self = [super init]) {
self._id = ID;
self.hadith_ar = ha;
self.hadith_en = he;
self.ref_ar = ra;
self.ref_en = re;
self.favourites = f;
}
return self;
}
What I'm doing wrong? Is there anything missing? Any help would be greatly appreciated. Thanks in advance :)
try this
-(id)initWithId:(NSInteger)ID hadith_ar:(NSString *)ha hadith_en:(NSString *)he ref_ar:(NSString *)ra ref_en:(NSString *)re favourites:(NSInteger )f
{
self = [super init];
self._id = ID;
self.hadith_ar = ha;
self.hadith_en = he;
self.ref_ar = ra;
self.ref_en = re;
self.favourites = f;
return self;
}
Try this one
-(id)initWithId:(NSInteger)ID hadith_ar:(NSString *)ha hadith_en:(NSString *)he ref_ar:(NSString *)ra ref_en:(NSString *)re favourites:(NSInteger )f
{
self = [super init];
__id = ID;
_hadith_ar = ha;
_hadith_en = he;
_ref_ar = ra;
_ref_en = re;
_favourites = f;
return self;
}

sqlite3 prepared statement fails if fk is null. It should not

I use Sqlite3 in my iOS app.
If I try to run the command from the console:
INSERT INTO documents (name,fk_1) VALUES ('pluto','')
everything is fine.
But when doing it via prepared statement, the same fails:
INSERT INTO documents (name,fk_1) VALUES (?,?)
saying "foreign key constraint failed".The value of fk_1 = ''.
The table documents is
CREATE TABLE "documents" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL ,"name" varchar,"attivita_id" integer NULL REFERENCES attivita(id) ON DELETE CASCADE)
I was supposing that I can use NULL value as FK, and I can, indeed, because from the command line (first query) it works. The same is not possible with prepared statements?
The code to execute a write is:
-(NSInteger)writeData:(NSDictionary* )data table:(NSString* )table
{
sqlite3_stmt *sqlStatement;
NSMutableArray *columns = [[NSMutableArray alloc] init];
NSMutableArray *values = [[NSMutableArray alloc] init];
NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithDictionary:data];
#try {
assert([data count] != 0);
if ([[data allKeys] count] == 0) return 1;
// Names/Values for INSERT
// id is AUTOINCREMENT
[temp removeObjectForKey:#"id"];
[columns addObjectsFromArray:[temp allKeys]];
NSString *cols = [columns componentsJoinedByString:#","];
NSMutableString *colNames = [[NSMutableString alloc] initWithString:
[NSString stringWithFormat:#"INSERT INTO %s (",[table UTF8String]]];
[colNames appendString:cols];
[colNames appendString:#")"];
// Values for INSERT
[values addObjectsFromArray:[temp allValues] ];
// Prepare the ? marks for bindings
NSMutableArray * marks = [NSMutableArray new];
for (int i=0 ; i < [values count]; i++)
[marks addObject:#"?"];
NSMutableString *s = [[NSMutableString alloc] init];
NSMutableString *valNames = [[NSMutableString alloc] initWithString:#" VALUES ("];
[valNames appendString:[marks componentsJoinedByString:#","]];
[valNames appendString:#")"];
[colNames appendString:valNames];
const char *sql = [colNames UTF8String];
#ifdef DEBUG
// NSLog(#"avvDB writeDATA insert string %#",colNames);
#endif
if(sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"DB:Problem with prepare statement write %s, data: %#",sqlite3_errmsg(db),data);
NSLog(#"DB:Query %#",colNames);
return 0;
}
// binding
for(int i = 0; i < [values count]; i++)
{
// According to the doc, if the 3rd value is a null pointer, the effect is similar to
// sqlite3_bind_null
if ([[values objectAtIndex:i] length] == 0 || [values objectAtIndex:i] == nil)
sqlite3_bind_text(sqlStatement, i+1, nil,-1, SQLITE_TRANSIENT);
else
{
[s setString:[NSString stringWithFormat:#"%#",[values objectAtIndex:i]]];
const char* currentValue = [s UTF8String];
sqlite3_bind_text(sqlStatement, i+1, currentValue,-1, SQLITE_TRANSIENT);
}
}
if (sqlite3_step(sqlStatement) == SQLITE_DONE) {
// NSLog(#"Location inserted on database");
}
else {
NSLog(#"DB:Error on write: %i %s %#",sqlite3_errcode(db),sqlite3_errmsg(db),data);
NSLog(#"DB:Query %#",colNames);
}
// if (sqlite3_exec(db, sql, NULL, NULL, NULL) == SQLITE_OK)
// {
// NSLog(#"Last id %llu %s",sqlite3_last_insert_rowid(db),sqlite3_errmsg(db));
// }
// NSLog(#"Ecexecuted write %#",colNames);
valNames = nil;
colNames = nil;
marks = nil;
s = nil;
}// end try
#catch(NSException* e)
{
NSLog(#"Eccezione in write %#",[e reason]);
}
#finally {
sqlite3_finalize(sqlStatement);
sqlStatement = nil;
return sqlite3_last_insert_rowid(db);
}
}
An empty string is not the same as NULL.
To set a parameter to NULL, use sqlite3_bind_null.
Alternatively, just don't mention empty parameters in the INSERT statement.

Displaying Integer value in a Label , int to String conversion?

How to display an integer value in a UILabel in ViewDidLoad? I did for text and date and image but how to convert int to string. I was trying with following code
NSString* label=[aa stringWithFormat:#"%d",((Comments *) [self.list objectAtIndex:0]).noofcomm]];
[self.comments2 setText:label];
but didn't work.Please help me.How to set with the Integer with UILabel?
This is my comments.h
#interface Comments : NSObject
{
NSInteger iD;
UIImage *photo;
NSString *name;
NSString *descrp;
NSDate *date;
NSString *msg;
NSInteger noofcomm;
NSInteger nooflikes;
}
#property(nonatomic,assign)NSInteger iD;
#property(nonatomic,retain)UIImage *photo;
#property(nonatomic,retain)NSString *name;
#property(nonatomic,retain)NSString *descrp;
#property(nonatomic,strong)NSDate *date;
#property(nonatomic,retain)NSString *msg;
#property(nonatomic,assign)NSInteger noofcomm;
#property(nonatomic,assign)NSInteger nooflikes;
#end
DBClass.m
#import "DBClass.h"
#import "Comments.h"
#implementation DBClass
- (NSMutableArray *) getMyComments{
NSMutableArray *wineArray = [[NSMutableArray alloc] init];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"ComntDB.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"An error has occured.");
}
const char *sql = "SELECT id, photo,name,descrp, time,msg,comments,likes FROM Com";
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement");
}
//
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
Comments *MyWine = [[Comments alloc]init];
MyWine.iD = sqlite3_column_int(sqlStatement, 0);
const char *raw = sqlite3_column_blob(sqlStatement, 1);
int rawLen = sqlite3_column_bytes(sqlStatement, 1);
NSData *data = [NSData dataWithBytes:raw length:rawLen];
MyWine.photo = [[UIImage alloc] initWithData:data];
MyWine.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
MyWine.descrp = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 3)];
MyWine.date=[NSDate dateWithTimeIntervalSince1970:sqlite3_column_double(sqlStatement,4)];
MyWine.msg = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,5)];
MyWine.noofcomm = sqlite3_column_int(sqlStatement, 6);
MyWine.nooflikes = sqlite3_column_int(sqlStatement, 7);
[wineArray addObject:MyWine];
}
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
#finally {
return wineArray;
}
}
#end
RootViewController.m
#import "RootViewController.h"
#import "Comments.h"
#import "DBClass.h"
#interface RootViewController ()
#end
#implementation RootViewController
#synthesize list;
#synthesize image2;
#synthesize name2;
#synthesize descrp2;
#synthesize msg2;
#synthesize date2;
#synthesize comments2;
#synthesize likes2;
- (void)viewDidLoad
{
DBClass * mywines =[[DBClass alloc] init];
self.list = [mywines getMyComments];
[self.image2 setImage:((Comments *) [self.list objectAtIndex:0]).photo];
[self.name2 setText:((Comments *) [self.list objectAtIndex:0]).name];
[self.descrp2 setText:((Comments *) [self.list objectAtIndex:0]).descrp];
NSDateFormatter* fmtr = [[NSDateFormatter alloc] init];
[fmtr setDateFormat:#"MM/dd/yy"];
NSString* label_str = [fmtr stringFromDate:((Comments *) [self.list objectAtIndex:0]).date];
[self.date2 setText:label_str];
[self.msg2 setText:((Comments *) [self.list objectAtIndex:0]).msg];
//[self.comments2 setText:((Comments *) [self.list objectAtIndex:0]).noofcomm];
// int solution = 1;
// [self.comments2 setText:[NSString stringWithFormat:#"%d", solution]];
// int solution2 = 1;
// [self.likes2 setText:[NSString stringWithFormat:#"%d", solution2]];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setImage2:nil];
[self setName2:nil];
[self setMsg2:nil];
[self setDescrp2:nil];
[self setComments2:nil];
[self setLikes2:nil];
[self setDate2:nil];
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NSInteger someInteger = myInteger;
NSString *someString = [NSString stringWithFormat:#"%d", someInteger];
myLabel.text = someString;
or
NSNumber *someNumber = #(myInteger);
NSString *someString = [someNumber stringValue];
myLabel.text = someString;
Both will work.
EDIT:
In your case, it will be something like this:
NSInteger someInteger = ((Comments *) [self.list objectAtIndex:0]).noofcomm;
NSString someString = [NSString stringWithFormat:#"%d", someInteger];
self.comments2.text = someString;
If it's still not working, FOR SURE the problem is somewhere else, and not with the conversion. Check with property noofcomm has a valid value, check if your label reference is ok (test with a random value before the conversion), and somethings like that.
You need to build an NSString
int someInteger = 10;
NSString *someString = [[NSString alloc] initWithFormat:#"%d", someInteger];
You can use something like [NSString string_from_int:42] in LCategory since 0.1.3: https://github.com/superarts/LCategory
_lbl_yourLabel.text=[NSString stringWithFormat:#"%d",[[dic valueForKey:#"your integer value"] intValue]];
On the top left is your label named "yourLabel" , "dic" is your json response dictionary where all the data is coming in key value terms, "your integer value" is the key for which the value will be assign to the label "yourLabel", we have taken intValue because we cannot assign integer value directly to the label.
or you also can try below:
int anyInteger = 13;
NSString *yourString = [[NSString alloc] initWithFormat:#"%d", anyInteger];
self.yourLabel.text = yourString;

Memory leak sqlite iOS application

I'm currently battling through some memory leaks and having some serious trouble working out one of the last ones I have left. The leaks instrument shows several leaks all coming from the same method for various different reasons mostly attributed to either NSCFString, NSMutableArray and a class I made called GraphData. I have attempted to fix it in a few different ways to no avail so hopefully some light can be shed on this problem which hopefully is something simple I have overlooked.
Here is some code:
// the offending, leaking method
-(NSMutableArray*)fillDataInArray:(NSInteger)keyphrase_id{
NSLog(#"Keyphrase_id:%d", keyphrase_id);
NSDate *startdate = [self getDateForApplicationInstalled];
NSDate *enddate = [NSDate date];
NSString *dateString1=[[NSString alloc] initWithString: [fmt stringFromDate:startdate]];
NSString *dateString2=[[NSString alloc] initWithString: [fmt stringFromDate:enddate]];
NSMutableArray *newDataNew = [[NSMutableArray alloc]init];
self.newData = newDataNew;
[newDataNew release];
selStmt = nil;
if (!selStmt)
{
const char *sql = "select distinct position, key_time from ranking where keyphrase_id = ? and key_time between ? and ? order by key_time";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
NSInteger n = keyphrase_id;
sqlite3_bind_int(selStmt, 1, n);
sqlite3_bind_text(selStmt, 2, [dateString1 UTF8String] , -1, SQLITE_TRANSIENT);
sqlite3_bind_text(selStmt, 3, [dateString2 UTF8String] , -1, SQLITE_TRANSIENT);
NSLog(#"SQL query is: [%s]", sql);
}
if (!selStmt)
{
NSAssert1(0, #"Can't build SQL to read keyphrases [%s]", sqlite3_errmsg(database));
}
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{
GraphData *item = [[GraphData alloc]init];
item.key = sqlite3_column_int(selStmt, 0);
item.value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selStmt,1)];
[newData addObject:item];
[item release], item = nil;
}
sqlite3_reset(selStmt); // reset (unbind) statement
[dateString2 release];
[dateString1 release];
return newData;
}
//GraphData.h
#interface GraphData : NSObject{
NSInteger key;
NSString *value;
}
#property (nonatomic, readwrite) NSInteger key;
#property (nonatomic, retain) NSString *value;
-(id)initWithPrimaryKey:(NSInteger) xid;
-(id)initWithName:(NSString *)n key:(NSInteger)i;
#end
//GraphData.m
#import "GraphData.h"
#implementation GraphData
#synthesize key,value;
-(id)initWithPrimaryKey:(NSInteger) xid{
self.key = xid;
self.value = #"";
return self;
}
-(id)initWithName:(NSString *)n key:(NSInteger)i{
self.key = 0;
self.value = n;
return self;
}
-(void)dealloc{
[value release], value = nil;
[super dealloc];
}
#end
Thanks for looking at my post!
the leak tool tells you where a leaked object has been created. As NSCFString, NSMutableArray and GraphData objects are leaked from this method, let's have a look how this could happen.
You insert GraphData objects (containing string objects) only in an NSMutableArray and they seem to be properly released. So to leak a GraphData object that is created inside this method, the array containing the elements has to be the leak.
Please check the callers of the method. I assume one of them is retaining (and not releasing) the return value of the method.
Also, your initializers have to be changed to call super's init, but this is not related to the leak. An example:
-(id)initWithPrimaryKey:(NSInteger) xid
{
self = [super init];
if (self) {
self.key = xid;
self.value = #"";
}
return self;
}

Resources