Returning a string - objective-c

I have just started with Objective-C and have a (probably) very, very basic question/problem.
int testf(int x){
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd.MM.yyyy"];
NSString *infstr=[dateFormatter stringFromDate:[[NSDate] dateByAddingTimeInterval:(60*x)];
return infstr;
}
NSString *testString=testf(1);
I currently have the following problem: I don't know how to return a string from a function. I couldn't even figure it out through Google.
The aforementioned Code leads to a warning "Pointer from integer without a cast". I hope anyone does know a solution to this "problem" and is willing to share it with me.
Thanks in advance.

You need to create an NSString object using the int.
NSString *testf(int x) {
return [NSString stringWithFormat:#"%i",x];
}
NSString *testString = testf(1);

Just change your return type from int to an NSString pointer like so:
NSString* testf(int x){
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd.MM.yyyy"];
NSString *infstr=[dateFormatter stringFromDate:[NSDate dateByAddingTimeInterval:(60*x)]];
[dateFormatter release];
return infstr;
}
NSString *testString=testf(1);
Also your dateFormatter is leaking, so add the release statement as shown above.

Related

how to use nsdate string objec for later use?

I'm so fedup with NSDate string object.
currently I am generating an unique id on the bases of NSDate as follows:
NSDate *current_date = [[NSDate date]retain];
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"HHmmssddMMYY"];
NSString *unique_id=[df stringFromDate:current_date];
NSString * current_Test_id=[NSString stringWithString:unique_id];
NSLog(#"current_test_idString %#",current_Test_id);
The code above is generating unique id and prints successfully but if I am printing or accessing currtent_Test_id in another IBAction method then app crashes.
stringWithString will create an autorelease string, modify your code as
NSString * current_Test_id = [[NSString stringWithString:unique_id]retain];
Use this Method
- (NSString *)stringDateFromDate: (NSDate *) date{
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"HHmmssddMMYY"];
NSString *current_Test_id=[NSString stringWithString:[df stringFromDate:date]];
[df release];
NSLog(#"current_tst_id %#",current_Test_id);
return current_Test_id;
}
Call Method Like that
NSString *current_tst_id = [self stringDateFromDate:[NSDate date]];
an NSString (or any object, for that matter) created with a class method, and not an init method, will be autoreleased. This means on the next iteration of the event loop, current_Test_id is released, and now you have a pointer to a dead object.
See this similar question
As current_Test_id is instance method.
in the init (in case of mac os) or viewDidLoad (for ios) alloc+init it.
and then assign :
current_Test_id=[NSString stringWithString:unique_id]; //it will be in autorelease mode.
or
current_Test_id=[[NSString stringWithString:unique_id]retain];

Incompatible pointer type sending 'Class' to parameter of type 'NSDate *'

I have an NSDate category with following method
#implementation NSDate (DateUtility)
+(NSString *)dateTimeStringForDB {
NSDateFormatter *dateFormatForDB = [[NSDateFormatter alloc] init];
[dateFormatForDB setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *aDateStr= [dateFormatForDB stringFromDate:self];
[dateFormatForDB release];
return aDateStr;
}
#end
with this definition I receive a warning .
Incompatible pointer type sending 'Class' to parameter of type 'NSDate *'
However type casting self before assign it as argument suppresses this warning.
+(NSString *)dateTimeStringForDB
{
NSDateFormatter *dateFormatForDB = [[NSDateFormatter alloc] init];
[dateFormatForDB setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *aDateStr= [dateFormatForDB stringFromDate:(NSDate*)self];
[dateFormatForDB release];
return aDateStr;
}
Can we really not pass self as an argument in a category without typecasting it ? What is this feature dependent on , the compiler ? Looking for an answer before actually posting it as a question on SO I came across this, however I am still not clear as to what goes behind the scene.
You have created a class method, I suspect you really want an instance method. I assume you want to convert an instance of an NSDate (ie an object) into an NSString representation. Currently you are trying to convert the actual NSDate class into an NSString representation.
Change
+(NSString *)dateTimeStringForDB {
to
-(NSString *)dateTimeStringForDB {

Is there a way to get Xcode's debugger to show dates in local timezone (i.e., not UTC)?

I'm trying to debug code that makes pretty heavy use of dates which has me comparing tons of different NSDate values in the debugger. The debugger is displaying those dates in UTC format--for example:
date1 = (NSDate *) 0x01b11460 #"2012-02-15 18:55:00 +0000"
It would be a lot easier for me if it would show them in my local timezone as that is what the test code I'm debugging seems to be using.
I do have feeling that I'm missing something much more basic here so I'm hoping someone can enlighten me. Thanks in advance.
While a little "hackish" you can create a subclass of NSDate and override just the
-(NSString *)description;
method to return a date formatted however you want.
The debugger isn't doing any special decoding for you, it's just calling the "description" method of the object it wants to display. A handy trick... (Which is why all my objects publish a concise description suitable for viewing in a debugger.)
In the end, what worked best was in fact adding a Category for NSDate that just overrides the description method to return a string that represents the NSDate in my current timezone. I also made it DEBUG only as I really just need this override in place when debugging.
Here's the .h file I used:
#ifdef DEBUG
#interface NSDate (DebugHelper)
-(NSString *)description;
#end
#endif
and the .m file:
#ifdef DEBUG
#import "NSDate+DebugHelper.h"
#implementation NSDate (DebugHelper)
-(NSString *) description
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
return [dateFormatter stringFromDate:self];
}
#end
#endif
Thanks to Jim Hayes and jrturton for the discussion and ideas that led to this answer.
Just did the same thing, however instead of systemTimeZone I used localTimeZone (see the docs as to why it is slightly better). Also I noticed you are alloc'ing the dateFormatter object but never releasing it which is a leak.
Here's my category method:
-(NSString *) description;
{
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init]autorelease];
NSLocale *enUSPOSIXLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease];
[dateFormatter setLocale:enUSPOSIXLocale];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
NSString *dateString = [dateFormatter stringFromDate:self];
return dateString;
}

Converting Decimal to String to Decimal

I copied this code from another post. I tried the example, however, I am getting a EXEC_BAD_ACCESS. From what I have read, this error happens when trying to use an object that has been deallocated, but I just don't see where I am doing that:
The call
...
float weighted_average = num_of_passes / total_of_all_passes;
NSString *newNumber = [[NSString alloc] init];
newNumber = [self formattedStringWithDecimal:weightedAverage]; //weighted average (float) = 15.875145
...
The Function
- (NSString *)formattedStringWithDecimal:(NSDecimalNumber *)decimalNumber
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:2]; //two deimal spaces
[formatter setRoundingMode: NSNumberFormatterRoundHalfUp]; //round up
NSString *result =[NSString stringWithString:[formatter stringFromNumber:decimalNumber]];
[formatter release];
return result;
}
Call the method like this:
newNumber = [self formattedStringWithDecimal:[NSDecimalNumber numberWithFloat:15.434]];
You've tried to pass a primitive, but the method expects an object: an NSDecimalNumber. You've got to use the static convenience method numberWithFloat to create an object of that type.
And by the way, I have the feeling that
newNumber = [NSString stringWithFormat#"%.2f", 15.434];
could achieve the same result with less lines of code. Note this will not round up your number though.
You are returning an autoreleased object. Does the function that uses it retain it? If not, it could be released and then later (later run loop) its trying to be (re)used. Agreed on the enabling zombies to spot that kind of thing.

iPhone simple method definition and calling the current date/time

I'm very new to iPhone development, and I'm trying to write a function which will accept one parameter, and return the current date/month and store it in a variable.
But I'm getting a (null) value with NSLog.
Method:
-(NSString *) getNowDateMonth:(NSString *)type {
NSDate *now = [[NSDate alloc] init];
if (type==#"month") {
NSDateFormatter *monthFormat = [[NSDateFormatter alloc] init];
[monthFormat setDateFormat:#"MM"];
NSString *theMonth = [monthFormat stringFromDate:now];
[monthFormat release];
return theMonth;
} else if (type==#"day") {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd"];
NSString *theDate = [dateFormat stringFromDate:now];
//int setDate = theDate;
[dateFormat release];
return theDate;
}
[now release];
return NULL;
}
Calling the function to get value:
NSString *month = [self getNowDateMonth:#"month"];
NSLog(#"%#", month);
Am I going about this the right way?
First of all, compare the strings using [#"month" isEqualToString:type], because two strings containing the same text ("month") may not be equal by the == operator. == checks if they're the same string object, not strings object with the same contents.
Second of all, you're leaking the date when returning the month or day (not releasing now). You should use [NSDate date]; instead of [[NSDate alloc] init].
To sum up, a suggested better version of this method would be:
-(NSString *) getNowDateMonth:(NSString *)type {
NSDate *now = [NSDate date];
if ([#"month" isEqualToString:type]) {
NSDateFormatter *monthFormat = [[NSDateFormatter alloc] init];
[monthFormat setDateFormat:#"MM"];
NSString *theMonth = [monthFormat stringFromDate:now];
[monthFormat release];
return theMonth;
} else if ([#"day" isEqualToString:type]) {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd"];
NSString *theDate = [dateFormat stringFromDate:now];
[dateFormat release];
return theDate;
} else {
return nil;
}
}
Also, there are a few other points that can be taken into consideration to improve this method:
do not use NSString as type; use an enum
do not allocate NSDateFormatter on each call to the method; instead use a static variable in the method
You want to use NSDateComponents to reliably and easily extract unit information i.e. month, day, week etc from an NSDate.
See Date and Time Programming Guide for Cocoa.
Dates are a deceptively complex programing problem so Cocoa has a fully developed set of classes for dealing with them. However, the learning curve is a bit steep.