简体   繁体   中英

Objective-C Not Creating Synthesized Variables

I'm a beginning iOS developer, and still getting accustomed to this concept of synthesized variables and XCode automatically creating variables and setter/getter methods. I did quite a bit of research but was not able to find an answer that addressed what I'm facing.

I created a header class as follows:

#import "Card.h"

@interface PlayingCard : Card

@property (strong, nonatomic) NSString *suit;
@property (nonatomic) NSUInteger rank;

@end

And I have the following implementation class:

#import "PlayingCard.h"

@implementation PlayingCard

- (NSString *)contents
{
    NSArray *rankStrings = @[@"?",@"A",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"J",@"Q",@"K"];
    return [rankStrings[self.rank] stringByAppendingString:self.suit];
}

- (void)setSuit:(NSString *)suit
{
    if([@[@"♥︎",@"♦︎",@"♠︎",@"♣︎"] containsObject:suit]) {
        _suit = suit;
    }
}

- (NSString *)suit
{
    return _suit ? _suit : @"?";
}

@end

My error is, whenever I use the _suit variable I get an error from XCode saying:

Use of undeclared identifier '_suit'; did you mean 'suit'?

It was my understanding that _suit is generated automatically by the compiler and I should be able to access the "suit" property defined in the header file with "_suit". Is it because I'm overriding the compiler's automatically generated setter and getter methods? Changing "_suit" to "self.suit" seems to fix the problem, but I'm confused as to why it seems that my underscore synthesized variable is not being generated. Any insight to this would be greatly appreciated, thanks!

If you manually create both accessors (the setter and the getter) for an @property , the compiler assumes you don't need/want it to synthesize them -- and the corresponding instance variable -- for you. There are two possible solutions. Either declare the instance variable yourself:

@implemntation PlayingCard
{
    NSString *_suit;
}

Or, my preferred approach, use an explicit @synthesize statement above your custom accessors to tell the compiler that you do still want to synthesize an instance variable for the property:

@synthesize suit = _suit;

Note that the = _suit is necessary because for legacy reasons, a simple @synthesize suit; will default to naming the ivar suit without the underscore prefix.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM