0

我是objective-c的新手,也许我还没有非常清楚地了解委托的概念,但我希望通过使用它来做到这一点。我正在尝试在我的应用程序中实施委托。

想法是我有TableViewController用于NSMutableArray初始化TableView的类。我需要从我的DropDown班级重新初始化这个数组。我尝试使用委托来做到这一点,但还没有做到,也许它有问题。我可以通过对象传递TableViewControllerDropDown班级并编辑表格。但我想使用委托来完成它。

这是我的TableViewController.h

@protocol TableViewControllerdelegate;
@interface TableViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,MFMessageComposeViewControllerDelegate>
{
    ControllerType controllerType;
}

@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (retain, nonatomic) NSMutableArray *dataArray;
@property (retain, nonatomic) NSArray *imageArray;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andType:(ControllerType)type;
- (void)sendSMS: (NSString *) sms;

@end;

这是我的DropDown.h

#import "TableViewController.h"
@interface DropDownExample : UITableViewController <VPPDropDownDelegate, UIActionSheetDelegate> {
@private
    VPPDropDown *_dropDownSelection;
    VPPDropDown *_dropDownSelection1;
    VPPDropDown *_dropDownSelection2;
    VPPDropDown *_dropDownSelection3;
    VPPDropDown *_dropDownSelection4;
    VPPDropDown *_dropDownDisclosure;
    VPPDropDown *_msg;
    VPPDropDown *_dropDownCustom;

    NSIndexPath *_ipToDeselect;
}
+ (bool) uncheck:(UITableViewCell *) cell andData:(NSString *) data;
- (void)reloadData;
@end

这就是我尝试编辑我的 tableview 对象数组的方式

            TableViewController *newControll = (TableViewController*)[UIApplication sharedApplication].delegate;
            NSMutableArray *arrayWithInfo = [[NSMutableArray alloc] initWithObjects:AMLocalizedString(@"Status", nil),AMLocalizedString(@"Call", nil),AMLocalizedString(@"Location", nil),AMLocalizedString(@"Control", nil),AMLocalizedString(@"Sim", nil),AMLocalizedString(@"Object", nil),AMLocalizedString(@"Info", nil),nil];
            newControll.dataArray = arrayWithInfo;
            [arrayWithInfo release];
            [newControll.tableView reloadData];

我让它运行,但它'-[AppDelegate setDataArray:]: unrecognized selector sent to instance 在达到此代码后运行。

4

2 回答 2

1

好的,我不确定我是否做对了,但它最终让我明白了代表团是什么以及我为什么需要它。希望您在阅读我的场景后也能理解。

历史

以前,在我的 UITabBar 应用程序中,我想显示一个覆盖在我的视图控制器顶部的自定义表单视图,以输入姓名和电子邮件。

后来我还需要在另一个选项卡上的另一个视图控制器顶部显示相同的自定义叠加层。

当时我并不真正知道委托是做什么的,所以我用来解决这个问题的第一个方法是 NSNotificationCenter。我将相同的代码复制到我的第二个视图控制器并将其连接到按钮按下事件。

在另一个选项卡上按下第二个视图控制器上的按钮时,它肯定会显示我的自定义叠加层,就像我的第一个视图控制器一样。

然而,这就是问题开始的地方。

问题

我需要关闭我的自定义表单视图。所以使用 NSNotificationCenter,我发布了一个通知,通知的侦听器回调方法被告知关闭我的自定义视图。

问题是,使用 NSNotificationCenter,我的第一个选项卡和第二个选项卡中的所有侦听器都响应了发布的通知,因此,它不仅关闭了覆盖在我的第二个视图控制器之上的自定义表单视图,还关闭了我的所有自定义视图,无论自定义视图是从哪里打开的。

我想要的是当我点击“X”按钮关闭我的自定义表单视图时,我只希望它为自定义视图的单个实例关闭它,而不是我打开的所有其他实例。

解决方案:委托

这就是我最终点击的地方 - 委托。

使用委托,我告诉我的自定义表单视图的每个实例委托是谁,如果我要点击“X”按钮关闭我的自定义视图,它只会为打开的单个实例关闭它,所有其他视图控制器保持不变。

一些代码

对,到一些代码。

不确定这是否是最好的方法(如果我错了,请纠正我),但这就是我的做法:

// ------------------------------------------------------------
// Custom Form class .h file
// ------------------------------------------------------------

@protocol MyCustomFormDelegate <NSObject>

// if you don't put a @optional before any method, then they become required
// in other words, you must implement these methods
-(void)sendButtonPressed;
-(void)closeButtonPressed;

// example: these two methods here does not need to be implemented
@optional
-(void)optionalMethod1;
-(void)optioinalMethod2;

@end

@interface MyCustomFormView : UIView
{
    ...
    id<MyCustomFormDelegate> delegate;
}

...
@property (nonatomic, retain) id<MyCustomFormDelegate> delegate;

@end


// ------------------------------------------------------------
// Custom Form class .m file
// ------------------------------------------------------------

...

@implementation TruckPickerView

@synthesize delegate;

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if(self)
    {
        ...

        [btnSend addTarget:self selector:@selector(sendEmail) forControlEvent:UIControlEventTouchUpInside];

        ...

        [btnClose addTarget:self selector:@selector(closeForm) forControlEvent:UIControlEventTouchUpInside];
    }

    return self;
}

-(void)sendEmail
{
    // code sends email

    ...

    // ------------------------------------------------------------
    // tell the delegate to execute the delegate callback method
    //
    // note: the implementation will be defined in the 
    // view controller (see below)
    // ------------------------------------------------------------
    [delegate sendButtonPressed];
}

-(void)closeForm
{
    // ------------------------------------------------------------
    // tell the delegate to execute the delgate callback method
    //
    // note: the implementation will be defined in the 
    // view controller (see below)
    // ------------------------------------------------------------
    [delegate closeButtonPressed];
}



// ------------------------------------------------------------
// view controller .h file
// ------------------------------------------------------------

#import "MyCustomFormView.h"

// conform to our delegate protocol
@interface MyViewController <MyCustomFormDelegate>
{
    ...

    // create a single instance of our custom view
    MyCustomFormView *customForm;
}

@property (nonatomic, retain) MyCustomFormView *customForm;


// ------------------------------------------------------------
// view controller .m file
// ------------------------------------------------------------

@synthesize customForm;

-(void)viewDidLoad
{
    customForm = [[MyCustomFormView alloc] initWithFrame:....];

    // tell our custom form this view controller is the delegate
    customForm.delegate = self;

    // only show the custom form when user tap on the designated button
    customForm.hidden = YES;

    [self.view addSubview:customForm];
}

-(void)dealloc
{
    ...
    [customForm release];
    [super dealloc];
}

// helper method to show and hide the custom form
-(void)showForm
{
    customForm.hidden = NO;
}

-(void)hideForm
{
    customForm.hidden = YES;
}

// ------------------------------------------------------------
// implement the two defined required delegate methods
// ------------------------------------------------------------
-(void)sendButtonPressed
{
    ...

    // email has been sent, do something then close 
    // the custom form view afterwards

    ...

    [self hideForm];
}

-(void)closeButtonPressed
{
    // Don't send email, just close the custom form view 
    [self hideForm];
}
于 2012-10-30T14:28:29.090 回答
0

您收到该错误,因为(如错误所述)您正在向setDataArray:您的应用委托(AppDelegate 类)发送消息。

[UIApplication sharedApplication].delegate;

这将返回您的应用程序的委托。有几种方法可以找出哪个类是您的应用程序的委托,但通常它被称为 AppDelegate (如您的情况)并且它UIApplicationDelegate也在实现协议。

您不能简单地将其转换为完全不同的类。如果您的应用程序委托具有 ivar 或类型的属性,TableViewController您必须使用访问器来获取它。如果它是一个属性,您可以使用点表示法。如果它是 ivar,您可以实现返回 ivar 的 getter 方法,或者将其设为属性。

// assuming your app delegate has a TableViewController property called myTableViewController.
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
TableViewController *tableViewController = appDelegate.myTableViewController;

这将修复错误,但您对委托模式的使用也是错误的。我看不到您在哪里使用任何自定义委托。你转发声明一个TableViewControllerdelegate协议,但我没有看到它的任何声明,或者我没有看到你试图在哪里使用它。

于 2012-10-30T13:03:55.770 回答