【问题标题】:Objective-C access int from other classObjective-C 从其他类访问 int
【发布时间】:2013-07-04 08:43:02
【问题描述】:

我知道这个问题被问了很多,但我是 Objective-C 的新手。 我在第一个 viewcontroller.h 中的代码:

@interface ViewController : UIViewController
@property (nonatomic) int mutecounter;
@property (nonatomic) ViewController *targetLevelController;
@end

我在 .m 文件中的第一个视图控制器中的代码:

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
@synthesize mutecounter;
- (void)viewDidLoad
    {
    [super viewDidLoad];
    NSURL *musicFile = [[NSBundle mainBundle] URLForResource:@"Ambler" withExtension:@"mp3"];
    self.backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
    self.backgroundMusic.numberOfLoops = -1;
    self.backgroundMusic.volume = 0.3;
    [self.backgroundMusic play];
    [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"mutebutton.png"] forState: UIControlStateNormal];
    _targetLevelController=[[ViewController alloc]init];
    _targetLevelController.mutecounter = mutecounter;
}
- (IBAction)muteButton:(id)sender {
    if (mutecounter % 2 == 0){
        self.backgroundMusic.volume = 0;
        mutecounter = mutecounter + 1;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"unmutebutton.png"] forState: UIControlStateNormal];
    } else {
        self.backgroundMusic.volume = 0.3;
        mutecounter = mutecounter + 1;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"mutebutton.png"] forState: UIControlStateNormal];
    }
}

还有我在第二个 Viewcontroller.h 中的代码:

@interface LevelController : UIViewController
- (IBAction)muteButton:(id)sender;
@end

以及我在第二个 Viewcontroller.m 中的代码

#import "LevelController.h"
#import "ViewController.h"

@interface LevelController ()

@end
@implementation LevelController
int mutecounter2;
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSURL *musicFile = [[NSBundle mainBundle] URLForResource:@"Ambler" withExtension:@"mp3"];
    self.backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
    self.backgroundMusic.numberOfLoops = -1;
    self.backgroundMusic.volume = 0.3;
    [self.backgroundMusic play];
    ViewController *targetLevelController=[[ViewController alloc]init];
    mutecounter2 = targetLevelController.mutecounter;
    if (mutecounter2 % 2 == 0){
        self.backgroundMusic.volume = 0;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"mutebutton.png"] forState: UIControlStateNormal];
    } else {
        self.backgroundMusic.volume = 0.3;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"unmutebutton.png"] forState: UIControlStateNormal];
    }
}

- (IBAction)muteButton:(id)sender {
    if (mutecounter2 % 2 == 0){
        self.backgroundMusic.volume = 0;
        mutecounter2 = mutecounter2 + 1;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"unmutebutton.png"] forState: UIControlStateNormal];
    } else {
        self.backgroundMusic.volume = 0.3;
        mutecounter2 = mutecounter2 + 1;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"mutebutton.png"] forState: UIControlStateNormal];
    }

}

问题是代码不起作用。 有人可以帮助我吗? 我总是在 mutecounter2 中得到值 0。 但它应该是 1 或 2 或 3 之类的。 谢谢马蒂斯

【问题讨论】:

    标签: objective-c class integer


    【解决方案1】:

    这里有很多问题。我建议重新访问一些讨论应用程序架构的指南。例如, mutecounter2 不是实例变量,但它可能根本不应该存在。

    如果静音计数在您的应用程序中是全局状态,那么存储它的最简单位置可能是在您的应用程序的委托中。将 muteCounter @property 添加到委托,两个视图控制器都可以访问它。

    但是,如果您的第二个视图控制器总是由第一个推送,那么第一个可以在推送之前设置第二个的值。因此也很常见。

    除非 muteCounter 应该在应用启动时保持不变,否则不要使用 NSUserDefaults。


    再想一想,似乎@MatisDS 可能应该使用管理背景音乐的共享实例,包括静音计数器的包含等......虽然通常不鼓励共享实例,但在某些情况下它是有保证的,这似乎是其中之一,因为您只会播放一首背景音乐,并且可能需要在全球范围内进行管理。

    虽然 Peter Hosey 使用全局变量的建议非常有效,但似乎有足够的逻辑与所述变量的管理相关,将功能封装到一个位置可以节省代码并且更简单。

    【讨论】:

    • 感谢您的回答,我没有在委托文件中编码任何内容。你能解释一下为什么使用委托吗?
    • 我建议您从这里开始,并深入了解 iOS 应用程序设计模式。至此,您应该真正了解应用程序委托。 developer.apple.com/library/ios/ipad/#documentation/iPhone/…
    • @MatisDS:除了 bbum 建议的文档外,您还应该阅读“使用 Objective-C 进行编程”,其中包括如何声明实例变量等内容。您还将了解为什么不需要为此声明实例变量或使用@synthesize(更不用说两者)。 developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
    • 我不同意将全局状态存储在应用程序的委托中比将其存储在全局变量中更好。所做的只是使访问表达式更长。最好完全废除全局状态; 如果这不是一个选项,那么最不坏的解决方案是将其放入一个或多个定义明确的单例中,以便尽早推土机。
    • @MatisDS 因为NSUserDefaults 并非旨在成为架构不佳的应用程序的解决方法。您真的希望mutecounter 在您的应用程序运行之间保持不变吗?如果答案是“否,它应该始终以 0 值开头”,那么 NSUserDefaults 是错误的答案。
    【解决方案2】:

    我总是在 mutecounter2 中得到值 0。但它应该是 1 或 2 或 3 什么的。

    嗯……

    ViewController *targetLevelController=[[ViewController alloc]init];
    mutecounter2 = targetLevelController.mutecounter;
    

    您正在初始化一个 ViewController 实例。它有一个 mutecounter 属性,但你没有在任何地方初始化它。所以 mutecounter2 为 0。

    if (mutecounter2 % 2 == 0){
        self.backgroundMusic.volume = 0;
        mutecounter2 = mutecounter2;
        [self.muteButtonOutlet setBackgroundImage:[UIImage imageNamed:@"mutebutton.png"] forState: UIControlStateNormal];
    }
    

    你输入了那个条件块,因为 0 % 2 = 0。你将 volume 属性设置为 0,然后将 mutecounter2 设置为它自己,所以它仍然是 0(这行应该被删除,它什么也没做)。

    所以退后一步,我想知道您是否还需要 2 个视图控制器?虽然父/子视图控制器的概念在 iOS 5 中是可行的,但在 iOS 6 中通过在 Storyboard 中嵌入 Segue 更容易实现。看来您才刚刚开始,所以我建议您使用 Storyboards 开始。 Apple 在其文档中提供了一些 Storyboard 教程。

    如果你真的需要两个视图控制器,你通常会像这样直接将数据传递给视图控制器:

    ViewController *newVC = [[ViewController alloc] init]
    newVC.propertyName = someValue
    

    但是你的情况正好相反,所以看起来你是在尝试从另一个 VC 中“拉”一个值,而不是让一个值被推送。不要那样做,因为那样你的 VC 就会有不必要的依赖。

    但实际上,请使用故事板。

    【讨论】:

    • 我是 Objective-C 的新手,我想我正在使用故事板?在 xcode 中,我有一个 mainstoryboard.storyboard 文件,所以我想我使用故事板。
    • mutecounter2mutecounter 属性无关。它是在@implementation 中声明的全局变量。 (我认为提问者的意思是声明一个实例变量,并不是说它会产生任何真正的区别。)
    • @MatisDS 是的,听起来您当时正在使用情节提要,但我不确定您对它们的接受程度如何。通常,您将数据从一个 VC 传递到另一个 VC 的方式是为第一个 VC 的 prepareForSegue: 方法提供一个实现。阅读 Apple 提供的“您的第一个 iOS 应用程序”教程以获得更多信息。
    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多