'Build and Analyze' with XCODE 3.2.2

  • Here's a sample snippet of my code:

    - (NSDate *)offsetDate:(NSDate *)fromDate
                          byYears:(int)addYears
                          byMonths:(int)addMonths
                          byDays:(int)addDays {

    NSDateComponents *offset = [[NSDateComponents alloc] init];
    [offset setYear:addYears];
    [offset setMonth:addMonths];
    [offset setDay:addDays];

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    return [gregorian dateByAddingComponents:offset toDate:fromDate options:0];

    }

    Builds and runs just dandy .. but "Build and Analyze" coughs up:

    // method returns an object with a +1 retain count (owning reference)
    NSDateComponents *offset = [[NSDateComponents alloc] init];

    ... and at the end of the method:

    // object allocated and stored into 'offset' is no longer referenced after this point
    // and has a retain count of +1 (object leaked)
    }

    It appears that the analysis is saying I should retain offset immediately after it is set with *offset =:

    NSDate *result = [gregorian dateByAddingComponents:offset toDate:fromDate options:0];

    [offset release];

    return result;

    By the way, identical gotchas are picked up by B & A for gregorian.

    John Love

    John Love
    Touch the Future! Teach!
  • On Apr 24, 2010, at 2:02 PM, John Love wrote:

    > Here's a sample snippet of my code:
    >
    > - (NSDate *)offsetDate:(NSDate *)fromDate
    > byYears:(int)addYears
    > byMonths:(int)addMonths
    > byDays:(int)addDays {
    >
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    > [offset setYear:addYears];
    > [offset setMonth:addMonths];
    > [offset setDay:addDays];
    >
    > NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    > return [gregorian dateByAddingComponents:offset toDate:fromDate options:0];
    >
    > }
    >
    >
    > Builds and runs just dandy .. but "Build and Analyze" coughs up:
    >
    > // method returns an object with a +1 retain count (owning reference)
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    >
    > ... and at the end of the method:
    >
    > // object allocated and stored into 'offset' is no longer referenced after this point
    > // and has a retain count of +1 (object leaked)
    > }

    I don't understand what you're trying to say. The static analyzer is telling you the truth, because you are leaking two objects in that code, unless that code will only be run with GC enabled.

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Apr 24, 2010, at 13:02, John Love wrote:

    > Here's a sample snippet of my code:
    >
    > - (NSDate *)offsetDate:(NSDate *)fromDate
    > byYears:(int)addYears
    > byMonths:(int)addMonths
    > byDays:(int)addDays {
    >
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    > [offset setYear:addYears];
    > [offset setMonth:addMonths];
    > [offset setDay:addDays];
    >
    > NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    > return [gregorian dateByAddingComponents:offset toDate:fromDate options:0];
    >
    > }
    >
    >
    > Builds and runs just dandy .. but "Build and Analyze" coughs up:

    Not quite. You are leaking NSDateComponents objects (as the analyzer told you) so things are not quite "dandy".

    > // method returns an object with a +1 retain count (owning reference)
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    >
    > ... and at the end of the method:
    >
    > // object allocated and stored into 'offset' is no longer referenced after this point
    > // and has a retain count of +1 (object leaked)
    > }
    >
    > It appears that the analysis is saying I should retain offset immediately after it is set with *offset =:

    I think you meant to say "release", not "retain".

    > NSDate *result = [gregorian dateByAddingComponents:offset toDate:fromDate options:0];
    >
    > [offset release];
    >
    > return result;

    Yes, or you can just autorelease offset when you create it.

    Also, you should preferably follow the memory management rules about naming methods. Either autorelease gregorian before releasing it, or put "Create" somewhere in your method name.
  • I believe the problem is that you aren't releasing offset or gregorian before you return them. I expect that gregorian retains offset (or copies it and retains the copy without releasing the original).

    In general, if you aren't don't intend to retain an allocated object, autorelease it and let the receiver retain it like this:

    > NSDateComponents *offset = [[[NSDateComponents alloc] init] autorelease];

    and

    > NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

    On Apr 24, 2010, at 1:02 PM, John Love wrote:

    > Here's a sample snippet of my code:
    >
    > - (NSDate *)offsetDate:(NSDate *)fromDate
    > byYears:(int)addYears
    > byMonths:(int)addMonths
    > byDays:(int)addDays {
    >
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    > [offset setYear:addYears];
    > [offset setMonth:addMonths];
    > [offset setDay:addDays];
    >
    > NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    > return [gregorian dateByAddingComponents:offset toDate:fromDate options:0];
    >
    > }
    >
    >
    > Builds and runs just dandy .. but "Build and Analyze" coughs up:
    >
    > // method returns an object with a +1 retain count (owning reference)
    > NSDateComponents *offset = [[NSDateComponents alloc] init];
    >
    > ... and at the end of the method:
    >
    > // object allocated and stored into 'offset' is no longer referenced after this point
    > // and has a retain count of +1 (object leaked)
    > }
    >
    > It appears that the analysis is saying I should retain offset immediately after it is set with *offset =:
    >
    > NSDate *result = [gregorian dateByAddingComponents:offset toDate:fromDate options:0];
    >
    > [offset release];
    >
    > return result;
    >
    > By the way, identical gotchas are picked up by B & A for gregorian.
    >
    > John Love
    >
    >
    >
    > John Love
    > Touch the Future! Teach!
  • On Apr 24, 2010, at 1:33 PM, Quincey Morris wrote:

    > Also, you should preferably follow the memory management rules about naming methods. Either autorelease gregorian before releasing it, or put "Create" somewhere in your method name.

    FYI "Create" is for functions, "new" is for methods. The analyzer won't recognize one where the other is proper. There are also adornments you can use to override the analyzer's understanding, but I can't recall them right now.
    --
    David Duncan
    Apple DTS Animation and Printing
  • On Mon, Apr 26, 2010 at 9:24 AM, David Duncan <david.duncan...> wrote:
    > FYI "Create" is for functions, "new" is for methods. The analyzer won't recognize one where the other is proper. There are also adornments you can use to override the analyzer's understanding, but I can't recall them right now.

    They can be found here: http://clang-analyzer.llvm.org/annotations.html

    I would advise sticking with the correct naming scheme, rather than
    using the annotations to override their meaning. The annotations are
    most useful when you have a delegate method that needs to return a
    retained reference (-foo:newBar:). The analyzer won't pick up on "new"
    anywhere but at the beginning of the method name.

    --Kyle Sluder
previous month april 2010 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today