在其中一个任务中,我必须覆盖游戏逻辑的超类的getter方法(因此该方法将获得游戏逻辑的子类,而不是原始的子类)。
CardGameViewController.h:
#import <UIKit/UIKit.h>
#import "Deck.h"
#import "CardGame.h"
@interface CardGameViewController : UIViewController
@property (nonatomic) NSUInteger startingCardCount; // abstract
@property (strong, nonatomic) CardGame *game;
- (Deck *)createDeck; // abstract
- (void)updateCell:(UICollectionViewCell *)cell usingCard:(Card *)Card; // abstract
@endCardGameViewController.m:
#import "CardGameViewController.h"
...
// no @synthesize here, but works fine.
- (CardGame *)game
{
if (!_game) _game = [[CardGame alloc] initWithCardCount:self.startingCardCount
usingDeck:[self createDeck]];
return _game;
}
...
@endSetCardGameViewController.m:
...
@interface TSSetCardGameViewController()
@property (strong, nonatomic) CardGame *game;
@end
@implementation TSSetCardGameViewController
@synthesize game = _game; // Compiler *will* complain if this line is commented out.
- (CardGame *)game
{
if (!_game) _game = [[SetCardGame alloc] initWithCardCount:self.startingCardCount
usingDeck:[self createDeck]];
return _game;
}
...
@end然后我得到了"_game“的”未声明标识符的用法“。所以我宣布
@property (strong, nonatomic) CardGame *game;但是我得到了相同的错误,所以我使用了"self.game“,这导致了一个糟糕的访问异常。我在Google上找不到任何东西,所以我到处修补,直到我发现这解决了问题:
@synthesize game = _game;现在,我的问题是为什么。我的理解是,新版本的Xcode会为我进行合成,除非我同时覆盖它的getter和setter。我确实覆盖了getter,但没有覆盖setter,所以从技术上讲,Xcode应该自动包含它。证据是,直到我将CardGameViewController子类化并特别重写了getter方法,Xcode才开始抱怨。(仅供参考,CardGameViewController和它的子类都没有*game的setter方法)
所以我有点困惑。请帮帮我!
发布于 2013-05-07 23:06:58
这里的问题是您有两个版本的_game。自从引入新的ABI (64位Mac和所有iOS)以来,每个子类都可以创建自己的ivars,而无需遍历其父类的ivars (即使它们的名称相同)。@synthesize创建的ivar是私有的。现在保持这种想法,让我们看看发生了什么:
您可以重写getter。编译器会说:“但是你仍然想让我为你创建一个setter,所以我会创建一个匹配它的ivar。”
这个问题的典型解决方案是,只需提供一个名为+gameClass的类方法,并让它返回要实例化的正确类,而不是覆盖-game。(有关此模式的示例,请参阅UIView中的+layerClass。)
https://stackoverflow.com/questions/16418532
复制相似问题