繁体   English   中英

iPhone协议委托传递数据

[英]iPhone Protocol Delegate Passing Data

我通过委托和协议传递字符串。 该字符串已正确接收到该类,但这在调用viewDidLoad方法之后发生。 viewDidLoad方法需要传递该字符串。

关于如何使viewDidLoad之前调用委托方法的任何想法? 我以为这就是委托/协议数据传递的想法。

创建并推送新视图的方法:

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

在ViewControllerTwo中:

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

编辑:感谢您的输入。 但是,我确实了解如何通过init方法传递此数据。 我最近一直在测试协议和代表,我想看看是否有一种方法可以做到这一点。 我已经成功地在另一个类中传递了这样的数据,并且它起作用了。 该协议方法被称为首先设置字符串。 这似乎是处理传递数据的一种更干净的方法。

我认为您可能会对Delegation的用途以及原因感到困惑。

例如,如果您正在该ViewController中执行某种操作,并且需要通知另一个子类该操作正在执行或该操作的结果,则可能需要在UIViewController子类中创建协议。

现在,为了使子类想要了解操作(接收者),它必须符合其头文件中的协议。

您还必须将delegate “设置”为receiving class/controller

有很多方法可以获取对receiving controller/class的引用以将其设置为delegate但是常见的错误是在已经创建了该类的情况下分配和初始化该类的新实例以将其设置为委托。这样做是将您新创建的类设置为委托,而不是已经创建并等待消息的类。

您要做的只是将一个值传递给新创建的类。 由于您刚刚创建此UIViewController类,因此所需要做的就是在receiver(ViewControllerTwo)的Property。

你的情况是一个NSString

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

当然不要忘记主要内容:

  @synthesize string; //Goes in ViewControllerTwo.m

现在,您的ViewControllerTwo无需设置器。

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

使用@synthesize时,setter和Getters是免费的。 只需将值传递给ViewController 除了委托外,实现与您的代码相同:

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

如果您需要在初始化阶段传递该字符串,则可以在init方法中传递它。

因此,在您的控制器中,您需要创建一个属性和一个附加的init方法,如下所示:

。H

@property (nonatomic, copy) NSString* myString;

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

.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;
}

然后,在任何需要的地方使用self.myString

如果您不使用ARC,请记住将其释放。

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

您可以为ViewControllerTwo创建自定义初始化程序吗,例如

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

    self.myString = aString;
    // other initialization

    return self;
}

您在ViewControllerOne中的初始化将是:

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

我不会为此使用协议。 要将数据从父视图控制器传递给子视图,请使用自定义初始化程序方法。

在ViewControllerTwo.h中:

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

然后在您的ViewControllerTwo.m中实现它:

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

然后在您的ViewController中调用它:

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

将数据放置在init方法或viewDidLoad中将不起作用,因为用户可以在不卸载视图或重新初始化视图控制器的情况下来回切换。

检索更改的数据的最佳位置是viewWillAppear控制器方法。 这样,每次用户切换时,数据都会被更新。

另一个最佳方法是使用MVC架构。 如果您有单独的模型类,将仅保存数据,则可以从任何控制器进行写入/更新。

暂无
暂无

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

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