我有几个观点,一个是SettingsMenu,另一个是Game。
我已在Game中初始化了backgroundMusic。如果SettingsMenu发生了变化,我希望在settingsMenu中运行backgroundMusicStop,但是backgroundMusicStop是我的Game类的一部分。
Game.h
-(void)backgroundMusicStop;
Game.m
-(void)backgroundMusicStop {
[backgroundMusic stop];
backgroundMusic.currentTime = 0;
}
SettingsMenu.m
-(IBAction)musicOptionSwitch:(id)sender {
if (backgroundMusicPlay == YES) {
backgroundMusicPlay = NO;
[Game backgroundMusicStop];
}
}
我已经调查了它并且我不明白如何修复它,我知道我需要让所有类都可以访问该方法,但我对如何做到这一点感到困惑,任何帮助都会非常感谢。
答案 0 :(得分:2)
问题在于这行代码:
[Game backgroundMusicStop];
在您的实现中, Game 是一个类名,您尝试在类上调用实例方法。有两种方法可以解决它:
要创建游戏实例,您需要以下内容:
Game myGame = [[Game alloc]init];
//depending on your implementation it could be different
或者,如果您选择第二个选项,则必须更改
-(void)backgroundMusicStop;
到
+(void)backgroundMusicStop;
我还建议你找一些书/网站来更好,更深入地理解类和实例变量/方法。
答案 1 :(得分:1)
我认为你想要做的最好的架构是:
创建一个Settings对象的实例并让它跟踪 您希望用户控制的每个选项的当前状态
从SettingsMenu
让您的游戏收听设置值的更改
这样做的好处是您的视图控制器只能通过更改数据模型(设置)进行通信,而不必相互了解。您的“设置”对象可以是单个应用程序,也可以是从应用程序委托中获取的普通对象。
首先创建设置数据模型:
// Settings.h
#import <Foundation/Foundation.h>
@interface Settings : NSObject
// A singleton so that the example stays simple
+ (instancetype)sharedSettings;
// YES/NO. Add other properties as needed.
@property (nonatomic, assign) BOOL musicShouldPlay;
#define MUSIC_SHOULD_PLAY @"musicShouldPlay"
@end
// Settings.m
#import "Settings.h"
@implementation Settings
// Guarantee only one instance
+ (instancetype)sharedSettings {
static dispatch_once_t onceToken;
static Settings *result = nil;
dispatch_once(&onceToken, ^{
result = [[Settings alloc] init];
});
return result;
}
- (instancetype)init {
self = [super init];
if (self) {
_musicShouldPlay = NO;
}
return self;
}
@end
进行更改的控制器:
// SettingsViewController.m
#import "SettingsViewController.h"
#import "Settings.h"
@interface SettingsViewController ()
@property (strong, nonatomic) IBOutlet UISwitch *musicSwitch;
@end
@implementation SettingsViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Make the display consistent with previous settings
[self.musicSwitch setOn:[[Settings sharedSettings] musicShouldPlay]];
}
// I'm presenting this using a modal segue from a "Change settings" button on the main controller,
// so it has a "Done" button
- (IBAction)done:(id)sender {
[ self dismissViewControllerAnimated:YES completion:nil];
}
// Switch value changes are connected to this in the storyboard
- (IBAction)changePlayState:(id)sender {
[[Settings sharedSettings] setMusicShouldPlay:[self.musicSwitch isOn]];
}
@end
对变化做出反应的控制器:
// ViewController.m
#import "ViewController.h"
#import "Settings.h"
@implementation ViewController
// Since this is the primary controller, I'll have it listen for its lifetime.
- (void)viewDidLoad {
[super viewDidLoad];
[[Settings sharedSettings] addObserver:self
forKeyPath:MUSIC_SHOULD_PLAY
options:NSKeyValueObservingOptionNew
context:nil];
}
- (void)dealloc {
[[Settings sharedSettings] removeObserver:self forKeyPath:MUSIC_SHOULD_PLAY];
}
// Here's where the KVO notifications are delivered.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:MUSIC_SHOULD_PLAY]) {
NSNumber *newValue = [change valueForKey:NSKeyValueChangeNewKey];
if ([newValue integerValue] == 1) {
NSLog(@"Request to turn music on");
} else {
NSLog(@"Request to turn music off");
}
}
}
@end