繁体   English   中英

iOS中的代表

[英]Delegates in iOS

我是iOS世界的新手,因此请忽略显而易见的内容。

我在另一个viewController(MainViewController)顶部推一个viewController(HelpViewController)。 当HelpViewController中发生特定动作时,我想更新MainViewController中的变量。 我知道我需要使用委托。 这是我的代表头...

@protocol ViewControllerDelegate <NSObject>
@required
- (void) switchToggled:(BOOL)status;
@end
// Protocol Definition ends here
@interface ViewDelegate : NSObject
{
    // Delegate to respond back
    id <ViewControllerDelegate> _delegate;
}
@property (nonatomic,strong) id delegate;

-(void)sendMessage:(BOOL)status; // Instance method

@end

和实施...

@implementation ViewDelegate

@synthesize delegate;

-(id)init {

    self = [super init];

    return self;

}

-(void)sendMessage:(BOOL)status
{
    [delegate switchToggled:status];
}

- (void)dealloc
{
    [super dealloc];
}
@end

因此,现在,如果我想实现Protocol ViewControllerDelegate,则需要在MainViewController中进行指定,具体操作如下:

MainViewController <ViewControllerDelegate>

#pragma mark - ViewControllerDelegate delegate
-(void)switchToggled:(BOOL)status{
    NSLog(@"Switch Toggled(%d) Message passed to MainViewController",status);
}

我的问题该如何指定对象属性需要指向的对象,以便它可以返回到MainViewController的“ switchToggled”。

我做的一种方法是在HelpViewController中具有如下属性-

MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.mainView = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];

HelpViewController.h
    @property (nonatomic) MainViewController *mainView;
HelpViewController.m
@synthesize mainView;
ViewDelegate *myDelegate = [[ViewDelegate alloc] init];
// assign delegate
myDelegate.delegate = mainView;
[myDelegate sendMessage];
[myDelegate release];

这是实现的正确方法,还是有更好的实现方法,还是我完全错了。

谢谢

你应该做:

// HelpViewController.h
@protocol HelpDelegate

- (void)switchToggled:(BOOL)status;

@end


// HelpViewController.m
@interface HelpViewController : UIViewController

@property (nonatomic, assign) id<HelpDelegate> delegate;

- (id)initWithDelegate:(id<HelpDelegate>)delegate

@end

@implementation HelpViewController
- (id)initWithDelegate:(id<HelpDelegate>)delegate
{
    if (self = [super init])
    {
        self.delegate = delegate;
    }
}

- (void)sendMessage:(BOOL)status
{
    [self.delegate switchToggled:status];
}


// MainViewController.h 
#import "HelpViewController.h"

@interface MainViewController.h : UIViewController <HelpDelegate>


// MainViewController.m

- (void)someMethod
{
    HelpViewController* viewController;
    viewController = [HelpViewController alloc] initWithDelegate:self];
    ...
}

#pragma mark - Help Delegate

- (void)switchToggled:(BOOL)status
{
    ...
}
  • 给委托人起一个清楚的名称,该委托人属于哪个类。
  • 您不需要ViewDelegate / ViewControllerDelegate的额外类/文件。 只需在它所属的类的标头中定义委托即可:在这种情况下为HelpViewController.n
  • 类似:在真实类MainViewController实现委托方法switchToggled:而不在多余/不必要的类ViewDelegate
  • 委托的目的是避免类依赖。 通过包括MainViewControllerHelpViewController创建这样的依赖。 正如我所展示的,这是不必要的,并且是错误的设计。
  • 您还创建了一个循环依赖项,因为MainViewController已经需要HelpViewController来显示它,现在他们彼此之间也需要彼此发送事件。
  • 或者,您可以将HelpViewController的委托公开,使其具有不带参数的init ,并期望用户使用helpViewController.delegate = self;进行设置helpViewController.delegate = self; 或者其他的东西。 但这仅在设置的委托是可选的时才有意义(在这里似乎不是这种情况,因此将其添加到init方法中是适当的)。

我告诉你我会做什么:

1)协议定义不错,但是不要创建ViewDelegate类,因此:

//ViewControllerDelegate.h
@protocol ViewControllerDelegate <NSObject>
@required
- (void) switchToggled:(BOOL)status;
@end

2)您可以在MainViewController中实现委托方法。

3)现在...要点:

    //interface
@interface HelpViewController : UIViewController //or whatever superclass..
{
    id <ViewControllerDelegate> _delegate;
}
@property (nonatomic,strong) id<ViewControllerDelegate> delegate;

@end
//implementation
@implementation HelpViewController

- (void)someMethodWhichCallsTheDelegate
{
    //do something
    ...
    // call delegate
    //if switchToggled: were optional then add the following
    //if ([self.delegate respondToSelector:@selector(switchToggled:)]) {
    [self.delegate switchToggled:status];
}
@end

4)现在,您必须分配代表:

//MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.delegate = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];

就是这样!

顺便说一句:如果此委托仅与HelpViewController有关,则在定义类接口的地方添加协议定义,则不必创建单独的头文件。 如果相反,该协议是“全局”协议,则在某种意义上可以分开声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM