不使用iVar将数据传递到segue目的地

时间:2013-08-19 12:00:34

标签: ios objective-c cocoa-touch ivar

自切换到故事板后,我通过

加载视图控制器
[self performSegueWithIdentifier:@"identifier" sender:self]

这完美无缺。现在,如果我想在目标视图控制器上设置任何属性,我实现方法prepareForSegue:sender:并设置我需要设置的属性。一切都按预期工作,没有任何问题。

自从我开始使用这种方法而不是旧的

MyViewController *vc = ....
vc.prop = @"value";
[self.navigationController pushViewController:vc];

我觉得将参数传递给目标视图控制器有点笨拙,特别是如果您尝试设置的值不仅仅是静态值。

让我们举个例子说,我有一个从服务器获取一些数据的按钮。数据返回时,它会创建一个新对象,然后显示一个新的视图控制器来显示该对象。要做到这一点,我打电话给performSegueWithIdentifier:sender:,但这就是结束。我的对象现在已被释放,不再存在,我无法将其传递给prepareForSegue:sender:方法,除非我将其存储在实例变量中。

这感觉非常可怕,因为该对象的持续时间并不比此操作更长,并且与我当前的视图控制器中的任何其他内容无关。

在这种情况下,我理解我可以简单地在新视图控制器中请求数据,但这只是一个例子。

我的问题是,是否还有另一种方法可以做到这一点而不会感到如此hacky?我可以将这些数据存入目标视图控制器而不将其存储在实例变量中吗?

我知道我仍然可以使用旧方法,但如果可以的话,我想坚持使用故事板方法。

3 个答案:

答案 0 :(得分:3)

sender的{​​{1}}参数与performSegueWithIdentifier:sender收到的参数相同。因此,如果您想向prepareForSegue:sender发送变量,prepareForSegue:sender就是您的朋友。在你的情况下:

<强> SomeViewController.m

sender

答案 1 :(得分:0)

接受的解决方案是正确的,但是当数据在两个以上的segue之间共享时,我经常使用另一种方法。我经常创建一个单例类(我们称之为APPSession),并将其用作数据模型,创建和维护类似会话的结构,我可以在代码中的任何地方编写和读取。

对于复杂的应用程序,这个解决方案可能需要太多容易出错的编码,但我已经在很多不同的场合成功使用它。

APPSession.m

//
//  APPSession.m
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import "APPSession.h"

@implementation APPSession
@synthesize myProperty;

static APPSession *instance = nil;

// Get the shared instance and create it if necessary.
+ (APPSession *)instance {
    if (instance == nil) {
        instance = [[super allocWithZone:NULL] init];
    }

    return instance;
}

// Private init, it will be called once the first time the singleton is created
- (id)init
{
    self = [super init];

    if (self) {
        // Standard init code goes here
    }

    return self;
}

// This will never be called since the singleton will survive until the app is finished. We keep it for coherence.
-(void)dealloc
{

}

// Avoid new allocations
+ (id)allocWithZone:(NSZone*)zone {
    return [self sharedInstance];
}

// Avoid to create multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

APPSession.h

//
//  APPSession.h
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface APPSession : NSObject{

}

@property(nonatomic,retain) NSString* myProperty;

+ (id)sharedInstance;

@end

如何从应用代码的每个部分读取和写入属性 myProperty

// How to write "MyValue" to myProperty NSString * 
[APPSession instance] setMyProperty:@"myValue"]
// How to read myProperty
NSString * myVCNewProperty = [[APPSession instance] myProperty];

通过这种机制,我可以安全地在第一个ViewController中的APPSession中编写一个值,对另一个执行segue,执行另一个segue到第三个,并使用在第一个segue期间写入的变量。

它或多或少像Java EE中的SessionScoped JavaBean。请随意指出这种方法存在的问题。

答案 2 :(得分:0)

所有这些答案都是正确的,但我找到了一种很酷的方法。我只在iOS 7和iOS 8中测试过

在声明并设置您希望传递的对象的值之后,在prepareForSegue方法中,

    [segue.destinationViewController setValue:event forKey:@"property"];
//write your property name instead of "property