我是一名初级iOS开发人员,并且仍然习惯于这个合成变量的概念,而XCode会自动创建变量和setter / getter方法。我做了很多研究,但未能找到解决我面临的问题的答案。
我按如下方式创建了一个标题类:
#import "Card.h"
@interface PlayingCard : Card
@property (strong, nonatomic) NSString *suit;
@property (nonatomic) NSUInteger rank;
@end
我有以下实现类:
#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
我的错误是,每当我使用_suit变量时,我都会收到来自XCode的错误说:
Use of undeclared identifier '_suit'; did you mean 'suit'?
我的理解是_suit是由编译器自动生成的,我应该能够访问"诉讼"使用" _suit"在头文件中定义的属性。是因为我重写了编译器自动生成的setter和getter方法吗?改变" _suit" to" self.suit"似乎解决了这个问题,但我很困惑为什么我的下划线合成变量似乎没有被生成。非常感谢对此的任何见解,谢谢!
答案 0 :(得分:23)
如果为@property
手动创建两个访问器(setter和getter),编译器会假定您不需要/希望它为您合成它们 - 以及相应的实例变量。有两种可能的解决方案。要么自己声明实例变量:
@implemntation PlayingCard
{
NSString *_suit;
}
或者,我的首选方法是在自定义访问器上方使用显式@synthesize
语句告诉编译器您仍然想要为该属性合成实例变量:
@synthesize suit = _suit;
请注意,= _suit
是必要的,因为由于遗留原因,简单的@synthesize suit;
将默认命名为ivar suit
而没有下划线前缀。