在AppDelegate中调用一个函数?

5

Cocos2d中的UITextField示例中,根据最受欢迎的答案,我已经成功实现了它,但是遗漏了这一行。

[[[UIApplication sharedApplication] delegate] specifyStartLevel];

我将它放在我的场景中,然后收到了这个警告:

实例方法'-specifyStartLevel'未找到(返回类型默认为'id')

为什么会这样?我明明在我的AppDelegate的头文件和实现文件中定义了-specifyStartLevel...


编辑:声明specifyStartLevel

#import <UIKit/UIKit.h>

@class RootViewController;

@interface AppDelegate : NSObject <UIApplicationDelegate,UITextFieldDelegate> {
    UIWindow            *window;
    UITextField *levelEntryTextField;
    RootViewController  *viewController;
}
- (void)specifyStartLevel;
@property (nonatomic, retain) UIWindow *window;

@end

实现:

- (void)specifyStartLevel
{
    [levelEntryTextField setText:@""];
    [window addSubview:levelEntryTextField];
    [levelEntryTextField becomeFirstResponder];    
}

请提供specifyStartLevel声明的代码。 - zaph
4个回答

15

现在,你的类对于代理方法一无所知。你需要将代理引入到你的实现中,而不是你的接口中(以避免循环导入)。

例如:

#import "AppDelegate.h"

那么你应该将返回的委托转换为你嵌套方法调用中的委托类型。例如:

[(AppDelegate *)[[UIApplication sharedApplication] delegate] specifyStartLevel];

很奇怪。请在specifyStartLevel函数内设置断点或放置日志,以查看在从子类调用时是否被执行。 - sudo rm -rf
似乎它终究被调用了。然而,键盘看上去完全不可见。 - Saturn
好奇怪。我建议您在 Stack Overflow 上创建一个新的问题,描述您的问题,而不是在这里尝试解决它。 - sudo rm -rf
啊!我是在运行场景之后才创建UITextField的。而场景正试图从init方法打开键盘...谢谢您先生。 - Saturn
将什么变成竖向? 应用程序吗?您可以在Xcode项目设置中完成此操作。 - sudo rm -rf
显示剩余5条评论

5
  1. Add your method in AppDelegate.h file such as:

    - (void)Welcome
    
  2. Implement the method in AppDelegate.m file such as:

     - (void)Welcome
     {
         NSLog(@"Welcome")
    
     }
    
  3. Set the UIApplication delegate in method such as:

    AppDelegate *appDelegate=[UIApplication sharedApplication] delegate];
    
    [appDelegate Welcome];
    

3
您需要将AppDelegate导入到使用它的.m文件中。
[[[UIApplication sharedApplication] delegate] specifyStartLevel];

我希望使用一个包含快捷方式的标题来导入它。

GlobalData.h

#import "AppDelegate.h"
#define APPDELEGATE (AppDelegate *)[[UIApplication sharedApplication] delegate]

然后当我在任何课程中使用它时,我只需
#import "GlobalData.h"

// to gain access to the delegate
AppDelegate * appDelegate = APPDELEGATE;

我使用这种方法是因为我可以将更多的 #define 存储为一些全局常量(例如 soundFXVolume - #define SOUND_FX_V 0.6)。


这是一段与编程有关的内容,翻译成中文如下:
宏定义+1非常实用,通常我会说它们很邪恶,但在这种情况下非常有用。
- sudo rm -rf

3

-[UIApplication delegate] 返回一个类型为id<UIApplicationDelegate>的对象,因此编译器只知道该类型的对象响应的方法,即使您的自定义delegate响应于specifyStartLevel。您可以忽略警告或将-[UIApplication delegate]的返回值进行强制类型转换:

[(YourCustomAppDelegate *) [[UIApplication sharedApplication] delegate] specifyStartLevel];

强制转换比忽略警告更可取。警告被称为警告,有其原因,如果你养成忽略它们的坏习惯,可能会导致微妙的错误。 - Paul.s
@Paul.s:没错,但在这种情况下,忽略它肯定是安全的。 - mipadi
1
是的,它完全是无辜的,直到您更改方法签名并忘记在代码中更新。如果您已删除原始警告,则会收到一个新的提示,告诉您这一点。如果我有办法,我将始终使用“-Werror”编译。 - Paul.s
@Paul.s:使用动态类型语言的缺点之一。单元测试应该可以防止这种错误。但是,如果你愿意,你可以进行强制转换,所以两全其美。 - mipadi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接