0

I have this interface:

 #import <Foundation/Foundation.h>
 @interface Cards : NSObject {  NSString* effect;   NSString* image;   }
-(NSString*) effect;
-(NSString*) image;
-(void) setEffect: (NSString*) effect2;
-(void) setImage: (NSString*) image2;

@end

And this implementation:

#import "Cards.h"
@implementation Cards
-(NSString*) effect
{
    return [effect autorelease];
}
-(NSString*) image
{
    return [image autorelease];
}
-(void) setEffect: (NSString*) effect2
{
  effect = [[NSString alloc]initWithString:effect2];
}
-(void) setImage: (NSString*) image2
{
  image = [[NSString alloc]initWithString:@""];
}
-(void) dealloc
{
    [effect release];
    [image release];
    [super dealloc];
}
@end

Now if I make a Cards object such as Cards* card and then I run the metod setEffect like so: [card setEffect:@""]; It compiles but gives me a runtime error. Anyone know why? Thanks in advance!

csano
  • 13,266
  • 2
  • 28
  • 45
dgTheUser
  • 21
  • 3
  • Can you post the exact code you execute to get the error, and more details about the error, such as what it provides in the debugger window? – Tyler Jun 02 '11 at 06:52
  • By the way, you shouldn't be calling autorelease from the getter methods. Based on your setter implementations and dealloc, you own those pointers, so if you release them during a read, the next access to them could be to a deallocated string (badness). – Tyler Jun 02 '11 at 06:55

2 Answers2

0

I think you intended [image autorelease] to be [[image retain] autorelease]. Otherwise you will be autoreleasing it on every access of the property. You are also leaking on you set* methods as you're not releasing the older values prior to assigning the new one.

Deepak Danduprolu
  • 44,595
  • 12
  • 101
  • 105
  • @user780660 In general instead of implementing the getter methods yourself, you should implement them using objective-c @property. – ThomasW Jun 02 '11 at 06:58
0

In your getter methods, you are returning an autoreleased object which may have never been allocated to begin with. In other words, you are only allocating the objects in your setter. If you want your objects to be returned autoreleased, you have to allocate them first, and then return them autoreleased.

You may be better off to create properties for each ivar and have them retained and released by the class. You would still need to allocate them, if they have not been allocated, which you may want to override the getter to do. Something like this.

-(NSString *)effect {
    if (!effect) {
        effect = [[NSString alloc] init];
    }
return effect;

in your header you would have

NSString *effect;

and then the property

@property(nonatomic, retain) NSString *effect;

then in the implementation you would synthesize

@synthesize effect;

and release in your -(void)dealloc

[effect release];

This way after you make a Card class you can call things like

card.effect = @"Whatever goes in the effect property";

//assuming card is a Card object

Hope this helps.

Jamie
  • 5,090
  • 28
  • 26
  • Hey thanks for the help, but my app still crashes if I say card.effect=@"Something". I dont know why... – dgTheUser Jun 03 '11 at 03:07