【问题标题】:Where does the main-loop go when creating an iOS app?创建 iOS 应用程序时主循环在哪里?
【发布时间】:2012-07-06 22:54:50
【问题描述】:

我正在 Xcode 中为 iPhone 编写一个 iOS 应用程序,我在各自的 .h 和 .m 文件中创建了一些类及其方法(这是两个类,所以基本上我有两对 .h 和 .m文件)

我现在想开始编写我的主循环,每当用户点击播放按钮时都会执行该循环,但我究竟应该在哪里做呢?

我在 ViewController.m 中这样做吗?例如在这个方法里面:

- (IBAction)playPressed:(UIButton *)sender 
{
    // main loop executed in here ?
    // or simply message to the main loop to start executing is *sent* from here ?
}

我在这里读到了一个类似的问题,有人建议 AppDelegate。现在是 AppDelegate.m 还是 AppDelegate.h ?如果是这种情况,我是开始编写代码还是将所有内容都包含在内:

int main(int argc, char **argv)
{
   ....
}

在 Appdelegate 文件中?

我尝试在我创建的 game.m 文件中简单地开始实例化类并声明通用方法(不属于任何特定的类),我得到一个 initializer element is not a compile -时间常数在我尝试实例化任何东西时立即发出警告

有什么帮助吗?来自 c++ 它真的可以帮助我一劳永逸地澄清在哪个文件中编写我的主循环以及我是否应该将它包装在某种 int main() 函数中..

谢谢!

PS:

以防万一,我的 ViewController 将只包含一个播放按钮,只要按下它就会开始执行我的主循环,以及一个终止主循环执行的停止按钮

我已经在 ViewController.m 中创建了它们各自的方法:

- (IBAction)playPressed:(UIButton *)sender 
{
    // 
}

- (IBAction)stopPressed:(UIButton *)sender 
{
    //  ??
}

暂时是空的:)

【问题讨论】:

    标签: objective-c ios main


    【解决方案1】:

    每个 iOS 应用程序以及每个可执行文件都有一个入口点 - 这是 main()。一个可执行文件的入口点不能超过一个。如果您仔细查看该项目,您会发现在 Xcode 导航器的Supporting Files 组中自动生成了一个main.m 文件,如下所示:

    #import <UIKit/UIKit.h>
    
    #import "MyAppDelegate.h"
    
    int main(int argc, char *argv[])
    {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));
        }
    }
    

    你想要做什么还不够清楚,但这是一个很好的开始阅读 iOS 应用程序的结构和生命周期、objective-c 语法、熟悉 UIKit 以及至少一些 Apple 提供的框架.

    【讨论】:

      【解决方案2】:

      您在 iOS 应用程序中没有 main(好吧,从技术上讲,您确实有一个 main,但您不必担心编写它)。这一切都为你处理好了。运行循环也为您完成。您所要做的就是创建您的按钮,然后告诉它(通过 addTarget 方法)当它被按下时要运行哪个方法。

      更新: 这是你需要做的伪(ish)代码......

      [startButton addTarget:@selector(startPressed:)];
      [stopButton addTarget:@selector(stopPressed:)];
      
      -(void)startPressed {
        backgroundThread = [[NSThread alloc] initWithWhateverYouWantToRun];
        [backgroundThread start];
      }
      
      -(void)stopPressed {
        [backgroundThread stop];
      }
      

      在你的后台线程中,如果你想更新 UI,你会打电话给sendMessageOnMainThread(或类似的东西 - 目前不记得确切的细节!)

      【讨论】:

      • hmm..这可能更接近我正在寻找的内容,请查看我对乔治的回答.. :)
      • 创建一个线程并在后台执行您希望它执行的操作。但请记住,任何时候您想更新 UI,都必须在主线程中进行(提供给您执行此操作的方法)。
      【解决方案3】:

      iOS 上的编程方法与 C++ 方法不同。 实际上,在 C++ 中,您必须进行无限循环并在每一帧进行触摸、绘制所有内容等。 直到玩家按下“退出”并打破循环。 在 iOS 上,事情是不同的: 您已经有一个 main.m 文件,其中有一个 main 函数。 这将启动应用程序委托。该应用程序委托会告诉您应用程序何时完成启动、进入后台、进入前台等。 当应用程序完成启动后,您将进入您的第一个实际屏幕。 在那里,您添加子视图。您不会在每一帧都绘制它们。一旦您将视图添加到父视图,这将自动为您完成。 iOS 上的编程是基于事件的。您不必检查触摸并查看是否 触摸位置在按钮上,然后调用该按钮的方法。 相反,您为按钮设置了一个回调方法,一旦按下按钮,它就会自动为您调用。 当然,您首先需要分配按钮并将其添加到父视图中。

      一旦您习惯了这种基于事件的编程模型,您肯定会喜欢它。 一开始它可能会很不一样,也许它对你没有意义,但不要担心。 来自 C++ 背景肯定是一个好的开始。

      干杯,

      乔治

      编辑:在这种情况下,我可以提供更具体的信息: 因此,您从第一个屏幕中的 AppDelegate 开始。我们称之为 MainAppScreen。 现在,您需要添加这 2 个按钮并为它们设置选择器(回调方法)。我可以看到你已经这样做了。

      现在:

      - (IBAction)playPressed:(UIButton *)sender
      {
          running = TRUE;
          [self performSelectorInBackground:@selector(myLoop) withObject:nil];
      }
      - (IBAction)stopPressed:(UIButton *)sender 
      {
          running = FALSE;
      }
      - (void) myLoop
      {
          while(running)
          {
             //this is your loop. You can code in here.
          }
      }
      

      其中 running 是 MainAppScreen 类中的一个实例变量。

      希望这会有所帮助。

      干杯!

      【讨论】:

      • 如果有什么不同,我的应用程序将在屏幕上只有一个视图,它有一个播放按钮和一个停止按钮。每当按下播放按钮时,只要不按下停止按钮,我就希望开始执行一个循环(我称之为“主循环”)。现在这个循环将对 iPhone 的显示没有影响(它不是一个视觉应用程序......),即通过检查来自加速度计的值,它只会产生或不产生一些声音,仅此而已。在那种情况下,我的问题的答案是否更具体一些?我只是在某个地方专门写了那个循环吗?
      • 您将永远无法停止此操作,因为 myLoop 永远不会返回,因此 UI 不会响应并且您不会检测到按下停止。查看我关于使用线程的回答
      • 哎呀,我的错。编辑了答案。
      • 非常感谢你们两位!我会马上做,把所有事情都搞砸,然后带着更多问题回来:-P 干杯!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多