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.


