【问题标题】:Debugging trivial functions in Objective-C在 Objective-C 中调试琐碎的函数
【发布时间】:2014-08-21 10:35:52
【问题描述】:

最近我刚开始从事 iOS 游戏编程,我发现有几件事情令人困惑。 (仅供参考,我正在使用 makegamewith.us 上提供的代码开发一个简单的游戏)

首先,我刚刚发现只执行了 main 函数。我的意思是我们使用 main 函数来激活 iOS 模拟器,以便我们能够加载我们的游戏。然后我意识到断点只在主要功能中起作用。当我在其他文件(例如 bio.m,一个游戏组件)中放置断点时,尽管我使用函数在游戏中创建生物对象,但 Xcode 不会停止在该函数上。会调用iOS模拟器,然后自动加载游戏。

那么问题来了:那我该如何调试呢?

我假设在我运行游戏时调用了该函数,但 Xcode 只是忽略了其他文件中的任何其他函数,除了 main.m 中的 main 函数。

另外,我遇​​到了几个“找不到成员变量”的情况。我想知道如何防止这种情况发生。整个 sprite builder 发布到 Xcode 的东西看起来很模糊。如果有人能解释整个事情是如何运作的,我将不胜感激。

更新:

我意识到我没有显式调用我在其他文件中的任何函数(例如,如下所示的 Grid.m)。主函数是指 main.m 中的 int 主函数。所以问题可能是我没有在 main 中明确调用该函数? (但我认为 main.m 负责的是启动程序。)

在 main.m 中:

int main(int argc, char *argv[]) {

@autoreleasepool //if I put a breakpoint here this will definitely work
{
    int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
    return retVal;
    }
}

网格.m

#import "Grid.h"
#import "Creature.h"

// these are variables that cannot be changed
static const int GRID_ROWS = 8;
static const int GRID_COLUMNS = 10;

@implementation Grid {
    NSMutableArray *_gridArray;
    float _cellWidth;
    float _cellHeight;
}

- (void)onEnter
{
    [super onEnter];

    [self setupGrid];

    // accept touches on the grid
    self.userInteractionEnabled = YES;
}

- (void)setupGrid //****if I put breakpoint here, it doesn't work****
{
    // divide the grid's size by the number of columns/rows to figure out the right width and height of each cell
    _cellWidth = self.contentSize.width / GRID_COLUMNS;
    _cellHeight = self.contentSize.height / GRID_ROWS;

    float x = 0;
    float y = 0;

    // initialize the array as a blank NSMutableArray
    _gridArray = [NSMutableArray array];

    // initialize Creatures
    for (int i = 0; i < GRID_ROWS; i++) {
        // this is how you create two dimensional arrays in Objective-C. You put arrays into arrays.
    _gridArray[i] = [NSMutableArray array];
    x = 0;

    for (int j = 0; j < GRID_COLUMNS; j++) {
        Creature *creature = [[Creature alloc] initCreature];
            creature.anchorPoint = ccp(0, 0);
            creature.position = ccp(x, y);
            [self addChild:creature];

            // this is shorthand to access an array inside an array
            _gridArray[i][j] = creature;

            // make creatures visible to test this method, remove this once we know we have filled the grid properly
            creature.isAlive = YES;

            x+=_cellWidth;
        }

        y += _cellHeight;
    }
}

@end

【问题讨论】:

  • 对于在任何地方执行的任何代码,断点都会触发,所以我怀疑您没有正确调用这些函数。请发布一些示例代码。
  • 我认为你需要澄清你的意思。 “只执行主要功能”是什么意思?如果这意味着只有 main.m 文件中的 main 函数运行,那么这是不正确的。 “断点只在主函数中运行”什么是“主函数”?您可以在任何文件(例如 creature.m)中拥有一个函数,并且在执行该行代码时断点将中断。此外,您不应编辑 main.m 文件中的任何内容。只是假装它不在那里。它仅用于启动应用程序。您需要在此处包含一些代码。另外,我认为您需要从基础开始。
  • 如果你说你实际上是在利用main() 函数做几乎任何事情,那么你可能做错了。
  • 我不想听起来刺耳,但我在第一段就停止了阅读。友好的建议:读一两本书来学习术语
  • @Fogmeister 主函数是指 main.m 中的函数 int main。我以前在 C++ 方面有一些经验,所以我假设 Objective-C 中的所有内容都与 C++ 中的方式类似。这可能是错误的,但我认为面向目标的语言确实有很多共同点。

标签: ios objective-c xcode cocos2d-iphone spritebuilder


【解决方案1】:

看看你的main() 函数——它几乎唯一做的就是调用UIApplicationMain()。这适用于任何 iOS 应用程序。所以真正的工作是由UIApplicationMain() 完成的,我们应该了解一下。这里是the description from the docs

此函数从主体实例化应用程序对象 类并从给定类实例化委托(如果有)和 设置应用程序的委托。它还设置了主要事件 循环,包括应用程序的运行循环,并开始处理 事件。如果应用程序的 Info.plist 文件指定了一个主 nib 文件 要加载,通过包含 NSMainNibFile 键和有效的 nib 文件 值的名称,此函数会加载该 nib 文件。

因此,如果您的应用出现问题,很可能与应用委托、您的 AppController 类有关。在-[AppController application:willFinishLaunchingWithOptions:] 方法中设置断点——当应用程序准备好运行时,应用程序本身将在其委托上调用该断点。您在main() 中的UIApplicationMain() 调用看起来不错,因此调试器应该在您的...didFinishLaunching... 方法中遇到断点。逐步执行该方法并确保您正在设置窗口、设置根视图控制器等。如果您不确定需要发生什么,请尝试创建一个新的单视图项目并查看提供的代码在那里。

【讨论】:

  • 我认为这个问题会演变成“为什么我的[CCNode onEnter] 方法没有被调用?”
  • @trojanfoe 我希望你是对的。但是 OP 可能会通过逐步完成每个级别、检查文档并确保发生正确的事情来学习帮助自己。 (我们可以做梦,对吧?)目前,OP 似乎认为调试器不会中断除main() 之外的任何功能,而按照我上面描述的操作将表明这不是真的。
猜你喜欢
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2012-07-31
  • 1970-01-01
相关资源
最近更新 更多