从Appdelegate触发ViewController中的委托方法

时间:2014-01-17 13:20:45

标签: ios objective-c

我正在尝试使用AppDelegate在viewcontroller via和NSTimer中触发委托方法。所以在AppDelegate中,我基本上有:

AppDelegate.h

@protocol TestDelegate <NSObject>

-(void)testFunction:(NSString *)testString;

@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) id<TestDelegate> testDelegate;
...
@end

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    [self.window makeKeyAndVisible];


    self.timer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                  target:self
                                                selector:@selector(trigger:)
                                                userInfo:nil
                                                 repeats:YES];
    return YES;
}

-(void)trigger:(id)sender {
   [self.testDelegate testFunction:self];
}

在我的视图控制器中,我有:

ViewController.h

@interface ViewController : UIViewController <TestDelegate>
    @property (nonatomic, strong) AppDelegate *appDelegate;
@end

ViewController.m

@implementation ViewController
   ...
   -(void)viewDidLoad {
       self.appDelegate = [[UIApplication sharedApplication] delegate];
       self.appDelegate.testDelegate = self;
   }

   -(void)testfunction:(NSString *)testString {
       NSLog(@"%@", testString);
   }
@end

当我在我的应用程序中加载ViewController时,没有任何反应?我知道NSTimer成功触发,但是没有触发委托方法。

4 个答案:

答案 0 :(得分:1)

您在哪里将VC指定为代理人?在初始化/视图加载期间,您的VC是否自行分配?如果您没有这样做,我会在ViewDidLoad中分配它。

- (void)viewDidLoad
{
     [super viewDidLoad];
     [[UIApplication sharedApplication]delegate].testDelegate = self;
}

此外,您可能希望将AppDelegate中的属性设置为弱而不是强,以避免在/如果它被解除时保留VC。

答案 1 :(得分:1)

使用:

[[UIApplication sharedApplication].testDelegate = self;

而不是所有:

self.appDelegate = [[UIApplication sharedApplication] delegate];
self.appDelegate.testDelegate = self;

答案 2 :(得分:1)

你的功能声明是:

-(void)testFunction:(NSString *)testString;

但你称之为:

[self.testDelegate testFunction:self];

因此您要将self发送到期望指向NSString的参数,这显然是不正确的。

另外,我不是使用计时器,而是像这样使用GCD:

double delayInSeconds = 10.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    if [self.testDelegate respondsToSelector:@selector(testFunction:)] {
        [self.testDelegate testFunction:@"Test String"];
    }
});

答案 3 :(得分:0)

检查

if(!testDelegate) {
   [self.testDelegate testFunction:self];
}

如果你的控制器在导航控制器中,那么循环查找你的控制器活动对象并分配代表。

但我会建议使用LocalNotification

这种功能