NSDateComponents not accepting settings

Discussion in 'Mac Programming' started by AlbuquerqueApac, Jan 14, 2012.

  1. macrumors member

    Joined:
    Jan 13, 2012
    #1
    Hello all, I'm new to the forum and to Objective C, but not to programming in general.

    Can anyone give me some tips here?

    Code:
     
    
    
    #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
       
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	NSDateComponents *comps = [[NSDateComponents alloc] init]; 
    	[comps setDay:1];
    	[comps setMonth:7];
    	[comps setYear:1984];
    	
    	
    	
    	NSLog(@"comps at this point is %Lf", comps);
    	
    	NSCalendar *g = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    	NSDate *dateofbirth = [g dateFromComponents:comps];
    	NSDate *now = [NSDate date];
    				   
    	double timeSince = [dateofbirth timeIntervalSinceDate: now ];
    	
    	
    	
    	
    				   
    	NSLog(@"your age %d", timeSince);
    	
    	
    	
    	[pool drain];
       
    	
    	
        return 0;
    }
    
    
    :apple:
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
  3. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #3
    Ok, I thought the autopool and pool drain would take care of any object leaks.


    Also, I am using float or double and my NSDate object is not accepting any of the values like:

    Code:
    
    #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
       
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	NSDateComponents *comps = [[NSDateComponents alloc] init]; 
    	[comps setDay:1];
    	[comps setMonth:7];
    	[comps setYear:1984];
    	
    	
    	
    	NSLog(@"comps at this point is %f", comps);
    	
    	NSCalendar *g = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
    	NSDate *dateofbirth = [g dateFromComponents:comps];
    	NSDate *now = [NSDate date];
    				   
    	double timeSince = [dateofbirth timeIntervalSinceDate: now ];
    	
    	
    	
    	
    				   
    	NSLog(@"your age %d", timeSince);
    	
    	
    	
    	[pool drain];
       
    	
    	
        return 0;
    }
    
    
     
  4. macrumors member

    Joined:
    Feb 2, 2009
    #4
    Fix your NSLog statements and you should be able to figure the rest out, read the link lee referred to. You are basically doing a conversion on your output and don't realize it.
     
  5. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #5
    Ok, well I have used about every format specify that could possibly apply.

    I finally just decided to use integer (unless there is a Date datatype that I am just not seeing.

    Code:
     
    
    
    #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
       
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	NSDateComponents *comps = [[NSDateComponents alloc] init]; 
    	[comps setDay:1];
    	[comps setMonth:7];
    	[comps setYear:1984];
    	
    	
    	
    	NSLog(@"comps at this point is %i", comps);
    	
    	NSCalendar *g = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar] ;
    	NSDate *dateofbirth = [g dateFromComponents:comps];
    	NSDate *now = [NSDate date];
    				   
    	int timeSince = [dateofbirth timeIntervalSinceDate: now ];
    	
    	
    	
    	
    				   
    	NSLog(@"your age %i", timeSince);
    	
    	
    	
    	[pool drain];
       
    	
    	
        return 0;
    }
    
    I am still getting incorrect output.

    Code:
    
    
    [Switching to process 299]
    Running…
    2012-01-14 15:51:24.933 HowManySecs[299:a0f] comps at this point is 1099568
    2012-01-14 15:51:24.936 HowManySecs[299:a0f] your age -869071884
    
    Also, I am a bit confused about the NSAutoReleasepool and my book (the big nerd ranch guide (which BTW, I don't feel this is up to par on the Deitel books etc)) doesnt do a very good job of explaining simple memory management in Objective C.

    Now, I am not asking anyone to do anything FOR me, I would just like to know if I can explicitly decalare an alloc & init within a NSAutoPool or does it not matter?

    Also, I do appreciate the help.
     
  6. chown33, Jan 14, 2012
    Last edited: Jan 14, 2012

    macrumors 603

    Joined:
    Aug 9, 2009
    #6
    Why do you think it's incorrect output?

    Yes, I'm asking you to think about and explain your reasoning.

    You're asking for the time interval since now, for a date in the past (date of birth). Simple logic suggests that will be a negative number, where now is the zero point on a number line, and positive times (intervals added to now) represent times after now, and negative ones represent times before now.

    If you want the time interval between date-of-birth and now, think about how you'd have to express that.


    What value do you expect timeSince to have? It's an integer (type int). What does that mean for time intervals?

    Did you expect an integer time-interval to be printed as years, months, days? If not, then what units are time intervals expressed as? You should look it up, because you need to know what units your values represent. Is it seconds, minutes, days, millifortnights, or what?


    Code:
    	[COLOR="Red"]double[/COLOR] timeSince = [dateofbirth timeIntervalSinceDate: now ];
    				   
    	NSLog(@"your age [COLOR="red"]%d[/COLOR]", timeSince);
    You really need to read the format-specifiers reference doc.

    In the above code, timeSince is type double. The format specifier for that type is not %d, but %f. You can't possibly get %d to work with a double.

    The reason switching to ints worked is because %d is for ints (go read the doc to see this). So what you did is change the type to match the format-specifier, instead of changing the format-specifier to match the double type.

    Code:
    	NSLog(@"comps at this point is %i", comps);
    This format-specifier is bogus for a similar reason. What type is comps? Does that type match the %i?

    Do you know what a type is? Or are you expecting it to be like JavaScript where type varies depending on how a value is used?

    You said you're not new to programming, but which programming languages do you know? If it's not strongly typed, then you really need to study the concept of types.
     
  7. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #7
    Even %@!?


    But what do expect to happen when you print an object pointer as an integer?!

    What is happening is that the address of the object is being printed in decimal. (Or only 32-bits of the pointer if you're compiling a 64-bit app.)


    Autorelease pools only handle autoreleased objects. You probably haven't learnt much about them yet. Autorelease pools don't relieve you of your obligation to release objects that you need to.

    As you're coding for Mac OS X, you have 3 options. Learn and systematically apply the Memory Management Rules, turn on garbage collection, or turn on automatic reference counting.
     
  8. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #8
    on comps? That's a pointer. The only thing your going to get is a memory address.

    As for TimeSince thats not a pointer. its a double variable which should have the result of a comparison between two objects.

    I got a feeling I may have joined the wrong forum here.
     
  9. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #9
    Try it. ;)
     
  10. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #10
    ok...

    Code:
    
    
     comps at this point is <NSDateComponents: 0x10010c730>
    
    
    
    As I said, that is a pointer, not an object.


    the curious thing is that when I use %@ on timeSince, I get a EXC_BAD_ACCESS error.
     
  11. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #11

    Hmmm... When I run (on Mac OS X 10.7.2):
    Code:
    	NSLog(@"comps at this point is %@", comps);
    
    I get:
    Code:
    2012-01-15 09:54:11.928 DateComponents[35494:707] comps at this point is <NSDateComponents: 0x1001147a0> Calendar: (null) / Time Zone: (null)
     Era: 9223372036854775807
     Year: 1984
     Month: 7
     Day: 1
     Hour: 9223372036854775807
     Minute: 9223372036854775807
     Second: 9223372036854775807
     Week of Month: 9223372036854775807
     Week of Year: 9223372036854775807
     Year for Week of Year: 9223372036854775807
     Weekday: 9223372036854775807
     Weekday Ordinal: 9223372036854775807
     Quarter: 9223372036854775807
    

    %@ is not %p. %@ will print out the result of sending description to the object.
     
  12. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #12
    Is it the verison of Xcode I am using?

    the only result I get is a memory address (I apologize for being short, but I am frustrated).

    yes I did try %@ and all it printed, for me anyway, is a memory address.

    I am using Xcode on SL version 4 I believe.
     
  13. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #13
    It won't be your version of XCode, it'll be your version of Mac OS X. If Snow Leopard is not giving you the output you need using a simple format specifier, you'll need to do custom output such as.

    Code:
    NSLog(
        @"comps at this point is year=%d, month=%d, day=%d", 
        [comps year],
        [comps month],
        [comps day]
      );
    
     
  14. macrumors 603

    Joined:
    Aug 9, 2009
    #14
    Why do you find that curious? What did you expect to happen? Those are not rhetorical questions. You really need to work this through, because there are some fundamental and very important gaps in your apparent reasoning process.

    If %@ is for object references, is timeSince an object reference? If not, what type is it? Exactly what format-specifier is appropriate for the type of timeSince?

    For a timeSince type that isn't an object reference, what did you expect to happen if the value is interpreted as an object reference (i.e. as a pointer to an object)?


    How could we tell? You haven't identified the version of Xcode you're using.

    Imagine how frustrating it is for us, trying to answer your questions with insufficient information.

    Post actual error messages.
    Describe what you expected to happen (and why).
    Describe what actually happened (with actual output).
    If you make several variations of the code, post the actual code of each variation, and the actual output of each.

    In short:
    Be specific.
    Be systematic.


    What is "SL version 4"? Do you mean 10.6.4?

    Being specific is important.


    No, it's not a comparison between two objects. It's a time interval. That is, it's the difference between two points in time, measured using some defined unit of measuring time.

    You need to read the reference doc to find out what units a time interval is measured in.
     
  15. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #15
    That fixed it. Thanks!


    I'm still getting a negative integer for the comparison, even after changing up the comparison

    Code:
     
    
    
    #import <Foundation/Foundation.h>
    
    int main (int argc, const char * argv[]) {
       
    	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    	NSDateComponents *comps = [[NSDateComponents alloc] init]; 
    	[comps setDay:1];
    	[comps setMonth:7];
    	[comps setYear:1984];
    	
    	
    	
    	NSLog(@"comps at this point is %@, the year is %d", comps,[comps year]);
    	
    	NSCalendar *g = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar] ;
    	NSDate *dateofbirth = [g dateFromComponents:comps];
    	NSDate *now = [NSDate date];
    				   
    	double timeSince = [now timeIntervalSinceDate:dateofbirth ];
    	
    	
    	
    	
    				   
    	NSLog(@"your age %d", timeSince);
    	
    	
    	
    	[pool drain];
       
    	
    	
        return 0;
    }
    
    I may try a different book. This nerd ranch guide by Aaron Hillegras is a little less technical then I'd like.
     
  16. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #16
    You haven't change the comparison. It's still the same.


    Try Kochan's Programing in Objective-C (4th edition).
     
  17. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #17
    Ok guys, cut the crap.

    I know that I am new to this language, I know that you guys have experience in it etc.

    I don't need condescending questions to my answers.

    I know that there are things I am missing.

    If you find my questions too bothersome or annoying to give a straightforward response, please do me the favor of moving on.
     
  18. chown33, Jan 14, 2012
    Last edited: Jan 14, 2012

    macrumors 603

    Joined:
    Aug 9, 2009
    #18
    Those aren't condescending questions I asked. They aren't even specific to Objective-C. They are fundamental to the problems you are experiencing (mismatched types, mistaken idea of time-intervals, etc.). If you're not interested in learning the fundamentals, you will continue to have problems.

    You also specifically wrote "... I am not asking anyone to do anything FOR me, ...", so I refrained from giving you the exact answer, instead presenting leading questions, which if followed by a logical reasoning process (and reading the relevant reference docs) should result in you finding the answer.
     
  19. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #19
    Thank you Jiminaus! That looks like the type of book I'm looking for.

    I will switch to it and finish this one after I have a better foundation in the language.
     
  20. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #20
    Chown33 gave you the answer in the 2nd paragraph of reply #6. I just pointed out that you hadn't actually made that change yet.
     
  21. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #21
    yes, but my problem is a lack of these fundamentals and some obscure references to a possible solution (which if you read above, you will realize are somewhat to do with the OS I am using or the way I asked NSLog to print my info.

    I am extremely interested in fundamentals, unfortunetely, I have some pretty terrible reference material to go by, namely

    The big ranch nerd book by Arron Hillegras leaves alot to be desired. By mistake for using this sorry excuse for a book. I will be sure to burn it immediately

    :D
     
  22. macrumors member

    Joined:
    Feb 2, 2009
    #22
    Once again your output is an int, whereas your interval is a double. You can't use %d and get the value you are looking for.
     
  23. chown33, Jan 14, 2012
    Last edited: Jan 14, 2012

    macrumors 603

    Joined:
    Aug 9, 2009
    #23
    You were pointed directly to the reference doc on format-specifiers in Lee's first reply (post #2).

    You said you were already familiar with programming in general. This suggests a certain experience with reading documentation. It also suggests an ability to use google to search for online reference docs. Example google search terms:
    nslog reference
    nsdatecomponents class
    nscalendar class


    Pointing out google search terms isn't condescending, either. I do it because sometimes people try things that are too specific. Or they don't try searching at all, because they think there are no useful online references.

    You also haven't answered my earlier question about exactly what your programming experience is, as in what languages you know. Without knowing your actual experience, it's difficult for me (or anyone else) to judge exactly what might be a useful Socratic question[*] and what might be perceived as condescending.

    You should probably read these:
    http://www.mikeash.com/getting_answers.html
    http://WhatHaveYouTried.com/



    [*] In particular, points 1-3.
     
  24. thread starter macrumors member

    Joined:
    Jan 13, 2012
    #24
    Well, thanks guys for all the responses, I appreciate your help (even if I was stubborn).

    :)


    My experience in programming has been mainly scripting languages (PHP, JS, etc) and Java is my only real compiled language I have worked extensively in. That's why the memory management is a new thing for me. Pointers, though I havent worked much with them, I have seen before in C (I am by no means a C expert, just enough to get by)
     
  25. macrumors 603

    Joined:
    Aug 9, 2009
    #25
    Compared to Java, Objective-C is much more laxly typed. The first thing you should do is treat all compiler warnings as errors. For example, you may have received a warning in Xcode about the NSLog statement you first posted. I say "may" because you still haven't said which version of Xcode you're using, and the ability to match arg-types to format-specifiers may not be present in older Xcode versions (or it may be broken).

    There is an Xcode build setting that forces all warnings to cause actual errors, but then I'd have to explain where to change it, and without knowing the Xcode version I'd just be guessing.

    In C, printf() has the same limitation as NSLog does: the format-specifier must match the actual type of the value. A modern C compiler has the ability to flag mismatches as warnings or errors.


    Objective-C is a strict superset of plain ordinary C. That means every valid C program is also a valid Objective-C program, with the same syntax and semantics. Thus, every C type is an Objective-C type, every C function is an Objective-C function, and so on. It also means you could use printf() or fprintf(), and the stdio library, if you wanted to. You might have to figure out where the output goes, because different Xcode versions present stdout and stderr in slightly different ways (by default).
     

Share This Page