简体   繁体   English

iPhone协议委托传递数据

[英]iPhone Protocol Delegate Passing Data

I am passing a string through a delegate and protocol. 我通过委托和协议传递字符串。 The string is received to the class correctly, but this occurs after the viewDidLoad method is called. 该字符串已正确接收到该类,但这在调用viewDidLoad方法之后发生。 The viewDidLoad method needs that string that is passed. viewDidLoad方法需要传递该字符串。

Any ideas on what I can do to get the delegate method to be called before viewDidLoad? 关于如何使viewDidLoad之前调用委托方法的任何想法? I thought this was the idea of the delegate/protocol data passing. 我以为这就是委托/协议数据传递的想法。

Method where new view is created and pushed: 创建并推送新视图的方法:

ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithNibName:@"ViewControllerTwo" bundle:nil];
two.delegate = self;
[two setString:theString];
[self.navigationController pushViewController:two animated:YES];
[two release]; 

In ViewControllerTwo: 在ViewControllerTwo中:

- (void)setString:(NSString *)str
{
    self.myString = str;
}

Edit: Thanks for the input. 编辑:感谢您的输入。 However, I do understand how to pass this data through the init method. 但是,我确实了解如何通过init方法传递此数据。 I have been testing protocols and delegates lately, and I wanted to see if there was a way to do this. 我最近一直在测试协议和代表,我想看看是否有一种方法可以做到这一点。 I have successfully passed data like this in another class and it worked. 我已经成功地在另一个类中传递了这样的数据,并且它起作用了。 The protocol method was called first setting the string. 该协议方法被称为首先设置字符串。 It seemed like a much cleaner way to handle passing data. 这似乎是处理传递数据的一种更干净的方法。

I think you might be a little confused about what Delegation is used for and why. 我认为您可能会对Delegation的用途以及原因感到困惑。

For example you might want to make a protocol in a UIViewController subclass if you were doing some kind of action in that ViewController and needed to inform another subclass that that action is being taken, or of the result of that action. 例如,如果您正在该ViewController中执行某种操作,并且需要通知另一个子类该操作正在执行或该操作的结果,则可能需要在UIViewController子类中创建协议。

Now in order for the subclass that wants to know about the action(the receiver), it has to conform to that protocol in it's header file. 现在,为了使子类想要了解操作(接收者),它必须符合其头文件中的协议。

You also must "set" the delegate to the receiving class/controller . 您还必须将delegate “设置”为receiving class/controller

There are many ways to get a reference to the receiving controller/class to set it as the delegate but a common mistake is allocating and initializing a new instance of that class to set it as the delegate, when that class has already been created.What that does is set your newly created class as the delegate instead of the class that's already been created and waiting for a message. 有很多方法可以获取对receiving controller/class的引用以将其设置为delegate但是常见的错误是在已经创建了该类的情况下分配和初始化该类的新实例以将其设置为委托。这样做是将您新创建的类设置为委托,而不是已经创建并等待消息的类。

What your trying to do is just pass a value to a Newly created class. 您要做的只是将一个值传递给新创建的类。 Since your just creating this UIViewController class all that needed for that is a Property in the receiver(ViewControllerTwo) . 由于您刚刚创建此UIViewController类,因此所需要做的就是在receiver(ViewControllerTwo)的Property。

In your case a NSString : 你的情况是一个NSString

 @Property (nonatiomic, retain) NSString *string; //goes in ViewControllerTwo.h

and of course don't forget in the main: 当然不要忘记主要内容:

  @synthesize string; //Goes in ViewControllerTwo.m

Now there is no need for a setter in your ViewControllerTwo . 现在,您的ViewControllerTwo无需设置器。

 - (void)setString:(NSString *)str  //This Method can be erased
    {                                  //The setter is created for free
        self.myString = str;          // when you synthesized the property
    }   

The setter and Getters are free when you use the @synthesize . 使用@synthesize时,setter和Getters是免费的。 Just Pass the value over to the ViewController . 只需将值传递给ViewController The implementation is identical to your code except for the delegate: 除了委托外,实现与您的代码相同:

  ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithNibName:@"ViewControllerTwo" bundle:nil];
    [two setString:theString];
    [self.navigationController pushViewController:two animated:YES];
    [two release];

if you need to pass that string in the initialization phase, you could pass it in the init method. 如果您需要在初始化阶段传递该字符串,则可以在init方法中传递它。

So in your controller you need to create a property and an additional init method like this: 因此,在您的控制器中,您需要创建一个属性和一个附加的init方法,如下所示:

.h 。H

@property (nonatomic, copy) NSString* myString;

-(id)initWithString:(NSString*)theString;

.m .m

@synthesize myString;

-(id)initWithString:(NSString*)theString {
    self = [super initWithNibName:@"ViewController" bundle:nil]; // I prefer to set the name of the controller internally
    if(self) {
        myString = [theString copy];
    }
    return self;
}

then, use self.myString wherever you want. 然后,在任何需要的地方使用self.myString

If you don't use ARC, remember to release. 如果您不使用ARC,请记住将其释放。

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

Can you create a custom initializer for ViewControllerTwo , eg 您可以为ViewControllerTwo创建自定义初始化程序吗,例如

- (id)initWithString:(NSString *)aString;
{
    self = [super initWithNibName:@"ViewControllerTwo" bundle:nil];
    if( !self ) return nil;

    self.myString = aString;
    // other initialization

    return self;
}

You initialization in ViewControllerOne would just be: 您在ViewControllerOne中的初始化将是:

ViewControllerTwo *vc = [[ViewControllerTwo alloc] initWithString:theString];
[[self navigationController] pushViewController:vc animated:YES];
[vc release];

I wouldn't use a protocol for this. 我不会为此使用协议。 To pass data from the parent view controller to the child, use a custom initialiser method. 要将数据从父视图控制器传递给子视图,请使用自定义初始化程序方法。

In the ViewControllerTwo.h: 在ViewControllerTwo.h中:

-(id)initWithString:(NSString *)str;

And then implement that in your ViewControllerTwo.m: 然后在您的ViewControllerTwo.m中实现它:

-(id)initWithString:(NSString *)str {
    self = [super self];
    if(self) {
        self.myString = str;
    }
    return self;

And then to call that in your ViewController one: 然后在您的ViewController中调用它:

ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithString:@"Cool String"];

Placing the data in an init method or a viewDidLoad won't work because the users can switch back and forth without unloading the view or reinitializing the view controller. 将数据放置在init方法或viewDidLoad中将不起作用,因为用户可以在不卸载视图或重新初始化视图控制器的情况下来回切换。

The best place to retrieve changing data is in the viewWillAppear controller method. 检索更改的数据的最佳位置是viewWillAppear控制器方法。 That way the data will be updated every time the user switches. 这样,每次用户切换时,数据都会被更新。

The another best way is using MVC architecture. 另一个最佳方法是使用MVC架构。 If you have separate model class which will just hold data and you may write/update from any controller. 如果您有单独的模型类,将仅保存数据,则可以从任何控制器进行写入/更新。

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

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