-3

I have a string in my header file named

NSString *enemy;

In implementation file i'm initializing that string from a plist file like this

NSString *path = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"];
NSDictionary *data = [NSDictionary dictionaryWithContentsOfFile:path];

NSDictionary *level_data = [data objectForKey:[@"Level" stringByAppendingFormat:@"%d", level]];

enemy = [level_data objectForKey:@"enemy"];

and then this "enemy" string, when i use it in method like this

-(void) addEnemy{
    if([enemy isEqualToString:@"Ostrich"]){
        [some_Obj valueCalc:t];
    }
}

it works fine for the first call to that "addEnemy" method but when i call this method again the string "enemy" throws an Exception. After debugging i came to know that at second call to the method "addEnemy" the string "enemy" shows "Variable is not NSString" in debugger.

but if i initialize "enemy" like this

enemy = [[NSString alloc] initWithString:[level_data objectForKey:@"enemy"]];

then it works quite fine.

Can anyone tell me why the above mentioned problem occurs?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Ashar
  • 217
  • 2
  • 13

3 Answers3

0

I have a string in my header file named

NSString *enemy;

This states this is an iVar.

You need to have a @property. And you must use strong in ARC or retain in MRC.

As everytime is getting released and new instance is created.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
  • 1
    in ARC `strong` is default, you don't have to do a thing – Rad'Val Mar 01 '13 at 05:03
  • 1
    you don't need to have a property, you can have an ivar as well, the default qualifier is still `strong`. – Rad'Val Mar 01 '13 at 05:06
  • 1
    But you don't know where in the header file that declaration is. If it's in the wrong spot (we don't know yet), it could be a global, not an ivar. – rmaddy Mar 01 '13 at 05:27
0

Declare in .h file and add properties to this variable and further information read this document.

@property (nonatomic, strong) NSString *enemy;

I think this is helpful to you.

Prasad G
  • 6,702
  • 7
  • 42
  • 65
0

The information you've provided isn't sufficient to say exactly what's wrong, but it sounds like the problem is that enemy is being deallocated before -addEnemy is called. You'll save yourself a lot of trouble by using @property accessors instead of setting and accessing instance variables directly.

In your header file:

@interface MyClass : NSObject

@property (nonatomic, strong) NSString *enemy;

@end

In your implementation (.m) file:

- (void)initializationMethod // Don't know what this really is in your code
{
    // get level_data from plist
    self.enemy = [level_data objectForKey:@"enemy"];
}

// Then in -addEnemy:
- (void)addEnemy
{
    if([self.enemy isEqualToString:@"Ostrich"])
    {
        [some_Obj valueCalc:t];
    }
}

// If (and only if) you're not using ARC, you need this. But, really you should use ARC.
- (void)dealloc
{
     [_enemy release];
     [super release];
}

This way, the synthesized setter method for the @property takes care of retaining enemy for you so it's not deallocated out from under you. You also really ought to read up on Objective-C Memory Management, particularly if you're not going to use ARC. See my answer to this question for some more reasons why it's a good idea to use accessor methods.

Community
  • 1
  • 1
Andrew Madsen
  • 21,309
  • 5
  • 56
  • 97