newbie: question: i have a memory leak: obj-c 2.0: modification of program in "Cocoa with Objective-C"

  • the code i am using is a modification of the code/problem found in
    "Cocoa with Objective-C", chapter 3.
    i have tried to use the objective-c 2.0 garbage collector
    methodology, using @property, @synthesize, etc.  when i run the code
    as listed below i get a leaking message.

    [Session started at 2008-02-01 23:33:37 -0500.]
    2008-02-01 23:33:38.070 SongsFoundationTool[28876:10b] ***
    _NSAutoreleaseNoPool(): Object 0x2040 of class NSCFString
    autoreleased with no pool in place - just leaking
    Stack: (0x96b10178 0x96a3e0f8)
    2008-02-01 23:33:38.075 SongsFoundationTool[28876:10b] Song 1: We
    Have Exposive
    2008-02-01 23:33:38.076 SongsFoundationTool[28876:10b] ***
    _NSAutoreleaseNoPool(): Object 0x2060 of class NSCFString
    autoreleased with no pool in place - just leaking
    Stack: (0x96b10178 0x96a3e0f8)
    2008-02-01 23:33:38.078 SongsFoundationTool[28876:10b] Song 2: Loops
    of Fury

    The Debugger has exited with status 0.

    when i include the commented out section, in the implementation file
    section, the description method, and use song1 and song2, in main,
    instead of song1.name and song2.name the program seems to run fine.

    The Debugger has exited with status 0.
    [Session started at 2008-02-01 23:38:24 -0500.]
    2008-02-01 23:38:24.375 SongsFoundationTool[28936:10b] Song 1: We
    Have Exposive
    2008-02-01 23:38:24.379 SongsFoundationTool[28936:10b] Song 2: Loops
    of Fury

    The Debugger has exited with status 0.

    please help me understand what's happening here.

    also, why was it necessary to use
    @property(copy, readwrite) NSString *name;
    @property(copy, readwrite) NSString *artist;
    instead of
    @property(readwrite) NSString *name;
    @property(readwrite) NSString *artist;

    thanks everyone, the code is below.

    // ....................... header file ...............

    #import <Cocoa/Cocoa.h>

    @interface Song : NSObject {
    NSString *name;
    NSString *artist;
    }

    @property(copy, readwrite) NSString *name;
    @property(copy, readwrite) NSString *artist;

    @end

    //.................... the implementation file ..................

    #import "Song.h"

    @implementation Song
    @synthesize name;
    @synthesize artist;

    /*
    -(NSString *) description
    {
    return [ self name ];
    }
    */
    @end

    //................................ main............................

    #import <Foundation/Foundation.h>
    #import "Song.h"

    int main (int argc, const char * argv[]) {

    Song *song1 = [ [ Song alloc ] init ];
        song1.name= @"We Have Exposive" ;
    [ song1 setArtist: @"The Future Sound Of Londown" ];

    Song *song2 = [ [ Song alloc ] init ];
    [ song2 setName: @"Loops of Fury" ];
    [ song2 setArtist: @"The Chemical Brothers" ];

    // Display Object
    NSLog( @"Song 1: %@", song1.name );
    NSLog( @"Song 2: %@", song2.name );

        return 0;
    }
  • On Feb 3, 2008 3:45 PM, George Greene <g.one...> wrote:
    > when i run the code as listed below i get a leaking message.

    Have you actually enabled garbage collection in the target properties?

    --Kyle Sluder
  • On Feb 3, 2008, at 12:45 PM, George Greene wrote:
    > int main (int argc, const char * argv[]) {
    >
    > Song *song1 = [ [ Song alloc ] init ];
    > song1.name= @"We Have Exposive" ;
    > [ song1 setArtist: @"The Future Sound Of Londown" ];
    >
    > Song *song2 = [ [ Song alloc ] init ];
    > [ song2 setName: @"Loops of Fury" ];
    > [ song2 setArtist: @"The Chemical Brothers" ];
    >
    > // Display Object
    > NSLog( @"Song 1: %@", song1.name );
    > NSLog( @"Song 2: %@", song2.name );
    >
    > return 0;
    > }

    Either enable Garbage Collection or surround the above w/an
    autorelease pool.  I suggest GC.

    Good songs, btw.

    b.bum
  • thanks, scott had told me this as well, but i thought it was still
    enabled from the last program i had done, the Cocoa Application
    Tutorial.  (i forgot it was a project setting. i, for some reason, was
    thinking it was an XCode preferences setting.

    ok, it works perfectly now that i've enable garbage collection for the
    project.

    for those who want to know:
    Project > Edit Project Settings
        then
          Section GCC 4.0-Code generation
              Objective-C Garbage collection          supported [-fobjc-
    gc]

    thanks Kyle,

    george.

    p.s. don't go far as i am new to this keep an eye out.  :-)
    thanks again, everyone.

    On Feb 3, 2008, at 4:41 PM, Kyle Sluder wrote:

    > On Feb 3, 2008 3:45 PM, George Greene <g.one...> wrote:
    >> when i run the code as listed below i get a leaking message.
    >
    > Have you actually enabled garbage collection in the target properties?
    >
    > --Kyle Sluder
  • On Feb 3, 2008, at 2:14 PM, George Greene wrote:
    > thanks, scott had told me this as well, but i thought it was still
    > enabled from the last program i had done, the Cocoa Application
    > Tutorial.  (i forgot it was a project setting. i, for some reason,
    > was thinking it was an XCode preferences setting.
    >
    > ok, it works perfectly now that i've enable garbage collection for
    > the project.
    >
    > for those who want to know:
    > Project > Edit Project Settings
    > then
    > Section GCC 4.0-Code generation
    > Objective-C Garbage collection          supported [-fobjc-
    > gc]

    Since your code is not dual mode, set the build setting to GC only.
    The compiler will generate slightly faster/smaller code in that it
    doesn't have to emit the goop necessary to allow the code to run dual
    mode...

    b.bum
  • thanks Bill,

    george.

    On Feb 3, 2008, at 5:20 PM, Bill Bumgarner wrote:

    > On Feb 3, 2008, at 2:14 PM, George Greene wrote:
    >> thanks, scott had told me this as well, but i thought it was still
    >> enabled from the last program i had done, the Cocoa Application
    >> Tutorial.  (i forgot it was a project setting. i, for some reason,
    >> was thinking it was an XCode preferences setting.
    >>
    >> ok, it works perfectly now that i've enable garbage collection for
    >> the project.
    >>
    >> for those who want to know:
    >> Project > Edit Project Settings
    >> then
    >> Section GCC 4.0-Code generation
    >> Objective-C Garbage collection          supported [-
    >> fobjc-gc]
    >
    > Since your code is not dual mode, set the build setting to GC
    > only.  The compiler will generate slightly faster/smaller code in
    > that it doesn't have to emit the goop necessary to allow the code
    > to run dual mode...
    >
    > b.bum
  • On Feb 3, 2008, at 12:45, George Greene wrote:

    > also, why was it necessary to use
    > @property(copy, readwrite) NSString *name;
    > @property(copy, readwrite) NSString *artist;
    > instead of
    > @property(readwrite) NSString *name;
    > @property(readwrite) NSString *artist;

    It isn't actually necessary. All you need to do to make the compiler
    warning go away is write:

    @property(assign, readwrite) NSString *name;
    @property(assign, readwrite) NSString *artist;

    which is what the "(readwrite)" version means anyway.

    What's at stake here is whether, if you pass a *mutable* string to
    setName or setArtist, it should keep a reference to the mutable string
    object in the instance variable, or whether it should keep a private
    copy of the string contents at that moment. Depending on the needs of
    your app, one or other might be the correct answer. The compiler is
    trying to warn you that the default of "assign" might not be what you
    wanted.

    The problem is that the object's conformance to NSCopying is a lousy
    way to arbitrate the possible ambiguity. It's really got nothing to do
    with NSCopying at all. And the poor wording of the warning message
    isn't a help either.

    I submitted a compiler bug for this a week or two ago, so we'll see if
    the compiler group listens to reason. ;)

    P.S. In your case, "(copy, readwrite)" looks like the proper choice,
    but that's just a guess.