从另一个类访问viewController的方法
我一直在尝试使用UIButton
动作来调用不同类(AppViewController)中的方法。我首先尝试在UIButton's
呼叫类(caller.m)
中创建视图控制器的一个实例,然后调用该方法,但保留导致EXC_BAD_ACCESS。从另一个类访问viewController的方法
我意识到我需要指向视图控制器的同一个实例,我现在努力确保视图控制器实例在caller.m.
正确声明我的AppViewController *viewController
声明中AppDelegate
,所以我的想法是从caller.m
引用同一个实例。
#import "caller.h"
#import "AppDelegate.h"
@implementation caller
- (id)initWithFrame:(CGRect)frame {
...
[btnSplash addTarget:viewController action:@selector(loadSplashView) forControlEvents:UIControlEventTouchUpInside];
....
}
但是,viewController仍然显示为未声明。我尝试了其他一些事情,但知道我可能错过了一些基本的东西。
:::: UPDATE ::::
好了,原来我需要创建下面这样的目标“的viewController”实际上是宣布并指向正确的实例:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
AppViewController* viewController = appDelegate.viewController;
现在正在正确调用视图控制器类中的方法。
对于这个问题更清楚的解释,更全面的版本,请到这里: Objective-c basics: Object declared in MyAppDelegate not accessible in another class
点击,将被捕获并在AppViewController执行的按钮时,您应该发表一个NSNotification。
所以这应该是: 发信人类:
[btnSplash addTarget:self
action:@selector(loadSplashView)
forControlEvents:UIControlEventTouchUpInside];
-(void)loadSplashView:(id)sender
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"notif_name" object:some_sender_object];
}
在目标类: 注册,即可获得该通知在视图的负荷:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(some_function:) name:@"notif_name" object:nil];
定义要采取的行动中本类:
-(void) some_function:(NSNotification *)notif {
//do something
// to access the object do: [notif object]
}
有多个乐的方式为对象提起诉讼,与其他物体的沟通和/或观察改变他们感兴趣的,包括:
- UIControl目标/行动绑定
- 协议
- 键/值观察(KVO)
- 通知书
我不认为在这种情况下通知是你想要的。当发布通知的对象不关心哪些对象正在观察通知,并且可以有一个或多个观察者时,通知是最合适的。在按下按钮的情况下,通常只需要特定的对象来处理该操作。
我会推荐使用协议。您会在iOS框架中看到很多使用的协议,基本上任何具有delegate
属性的类通常都会定义委托对象需要遵守的协议。该协议是两个对象之间的契约,使得定义该协议的对象知道它可以与符合该协议的对象进行通信,而不用考虑其类别或目的的任何其他假设。
下面是一个示例实现。道歉,如果有任何错误/遗漏。
在caller.h(I假定呼叫者是一个UIViewController):
@class Caller
@protocol CallerDelegate
- (void)userDidSplashFromCaller:(Caller *)caller;
@end
@interface Caller : UIViewController
id <CallerDelegate> delegate;
@end
@property (nonatomic, assign) id <CallerDelegate> delegate;
@end
在caller.m:
在otherViewController.m@implementation Caller
@synthesize delegate;
- (void)viewDidLoad {
// whatever you need
// you can also define this in IB
[btnSplash addTarget:self forAction:@selector(userTouchedSplashButton)];
}
- (void)dealloc {
self.delegate = nil;
[super dealloc];
}
- (void)userTouchedSplashButton {
if (delegate && [delegate respondsToSelector:@selector(userDidSplashFromCaller:)]) {
[delegate userDidSplashFromCaller:self];
}
}
:
// this assumes caller is pushed onto a navigationController
- (void)presentCaller {
Caller *caller = [[Caller alloc] init];
caller.delegate = self;
[self.navigationController pushViewController:caller animated:YES];
[caller release];
}
// protocol message from Caller instance
- (void)userDidSplashFromCaller:(Caller *)caller {
NSLog(@"otherVC:userDidSplashFromCaller:%@", caller);
}
[EDIT :CLARIFICATIONS]
我在再次查看您的问题和代码后意识到,我做了一些假设,您的代码中可能不是这样。您很可能仍应使用协议,但集成我的示例的确切方式取决于您的应用程序。我不知道什么类Caller
在您的应用程序中,但不管它是什么,它处理UIButtons,因此它很可能是视图控制器或视图。
你对没有正确的appViewController实例的评论让我怀疑你是否理解类和类的实例之间的区别。如果我的回答对你没有帮助,请张贴更多的代码来显示你如何创建和呈现你的视图控制器,以及你如何配置按钮,我可以尝试澄清我的答案。
谢谢你的帮助。这实际上还是很好的信息,但我不确定我是否在描述OP上的问题方面做得最好。但是,在更为一般的解释之后,我能够找到一个解决方案:http:// *。com/questions/5611972/objective-c-basics-object-declared-in-myappdelegate-not-accessible-in-another-cl – 2011-04-11 05:35:53
没问题,你的其他问题听起来像是完全不同的东西。我不知道你真正需要的只是了解属性。请注意,在我上面的示例中,“委托”是一个属性。有关更多信息,请注意属性主要是为iVar定义getter和setter的编译器快捷方式。 getter/setter方法是外部类在导入.h文件时知道的。快乐的编码! – XJones 2011-04-11 05:56:14
应用程序的各种对象之间的通信是设计级别决定。虽然iOS提供了在代码时间(属性)完成此操作的简洁方式 - 但它是通过硬耦合的。
真正的对象间通信不会在编译时绑定对象 - 这是只能通过遵循设计模式来保证的事情。
观察员&代表是两种最常用的模式,值得您学习when to use which one - see Observer vs Delegate。
当我调用视图控制器的不同副本的方法时,我实际上正在做一个NSLog。但在这里,我甚至没有编译,因为viewController看起来没有声明。 – 2011-04-10 12:13:30
如果你使用NSNotification,目标应该是“self” – 2011-04-10 12:15:46
[btnSplash addTarget:self action:@selector(loadSplashView)forControlEvents:UIControlEventTouchUpInside];并在 - (void)loadSplashView {[[NSNotificationCenter defaultCenter] postNotificationName:@“notif_name”object:some_sender_object];} – 2011-04-10 12:17:13