我不明白为什么我无法访问子类SetCardCardgameViewController中的self.cardButtons。父是CardgameViewController。
CardgameViewController.h:
#import <UIKit/UIKit.h>
#import "Deck.h"
@interface CardgameViewController : UIViewController
- (void) updateUI;
// protected
// for subclasses
- (Deck *)createDeck;
// must be overriden in SetCardGameViewController as contents is not to be used for instance
- (NSAttributedString *)titleForCard: (Card *)card;
- (UIImage *)backgroundImageforCard: (Card *)card;
@end
CardgameViewController.m
#import "CardgameViewController.h"
//#import "PlayingCardDeck.h"
#import "CardMatchingGame.h"
@interface CardgameViewController ()
@property (strong, nonatomic) CardMatchingGame *game;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
@property (weak, nonatomic) IBOutlet UISegmentedControl *matchMode;
@property (weak, nonatomic) IBOutlet UILabel *status;
@property (weak, nonatomic) IBOutlet UISlider *historySlider;
@property (weak, nonatomic) IBOutlet UILabel *historyOverview;
@end
SetCardCardgameViewController.h
#import "CardgameViewController.h"
@interface SetCardCardgameViewController : CardgameViewController
@end
SetCardCardgameViewController.m
#import "SetCardCardgameViewController.h"
#import "SetCardDeck.h"
#import "SetCard.h"
@interface SetCardCardgameViewController ()
@end
@implementation SetCardCardgameViewController
- (void)updateUI
{
for (UIButton *cardButton in self.cardButtons) {
}
}
这最后一个self.cardButtons没有得到认可。但cardButtons是父类的属性。为什么它不被认可?我同意它是私下声明的,但由于SetCardCardgameViewController是CardgameViewController的孩子,我想我可以访问它的所有属性和方法。或者我错了?
答案 0 :(得分:1)
你错误地将私有范围视为受保护的。
从语义上讲,由于Objective-C的动态特性,没有私有或受保护的范围。你可以像上面那样模仿私人范围;但是,.m文件中声明的方法或属性不能被其子类看到。将它们放在头文件中会使它们公开,并且通常是最常用的路径。如果绝对必须保护这些方法/属性,可以将该接口添加到单独的头文件中,然后将其导入子类中,如下所示:
CardgameViewController_Internal.h
@interface CardgameViewController (Private)
@property (strong, nonatomic) CardMatchingGame *game;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
@property (weak, nonatomic) IBOutlet UISegmentedControl *matchMode;
@property (weak, nonatomic) IBOutlet UILabel *status;
@property (weak, nonatomic) IBOutlet UISlider *historySlider;
@property (weak, nonatomic) IBOutlet UILabel *historyOverview;
@end
然后在SetCardCardgameViewController.m中:
#import "SetCardCardgameViewController.h"
#import "SetCardDeck.h"
#import "SetCard.h"
#import "CardgameViewController_Internal.h"
@implementation SetCardCardgameViewController
- (void)updateUI
{
for (UIButton *cardButton in self.cardButtons) {
}
}
@end
答案 1 :(得分:1)
您无法直接访问未在头文件中声明的任何属性,因为您没有从.m文件中导入任何符号,因此编译器不知道它们是否存在。
但是您的子类中的属性仍然存在,所以类似这样:
for (UIButton *cardButton in (NSArray*)[self valueForKey:@"cardButtons"])
将工作,而不必在头文件中公开该属性。
如果您需要强类型属性(如您所愿),可以将类别(@interface CardgameViewController ()
)移动到私有变量的单独标题(类似CardgameViewController+Private.h
),而不是将其声明为.m文件。然后,您将在基类和子类中导入此私有标头。