-10

好的,所以这是对我昨晚提出的问题的扩展。我对如何使用各种技术在视图控制器之间传递数据有了更深入的了解。我想走 MVC 路线,创建一个 Singleton 类似乎是与 MVC 最接近的概念。

基本上我创建了一个带有两个视图控制器和一个单例类的简单应用程序。我正在尝试将文本字段的值传递给 UILabel。无论出于何种原因,它都不起作用。这就是我的代码的样子。

视图控制器.h

#import <UIKit/UIKit.h>
#import "Model.h"
#import "ViewController2.h"

@interface ViewController : UIViewController {

NSString *text2pass;
}

@property (weak, nonatomic) IBOutlet UITextField *tf;
@property (weak, nonatomic) IBOutlet UILabel *btn;
- (IBAction)go:(id)sender;
@end

视图控制器.m

 #import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize tf = _tf;
@synthesize btn = _btn;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

NSString *tfstring = _tf.text;
NSLog(@"string = %@",tfstring);
}

 - (void)viewDidUnload
{
[self setTf:nil];
[self setBtn:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}

- (IBAction)go:(id)sender {
NSLog(@"btn pressed");

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController2 *vc2 = (ViewController2 *) [storyboard instantiateViewControllerWithIdentifier:@"home"];

text2pass = _tf.text;

[self passValues];

[self presentModalViewController:vc2 animated:YES];
}

-(void) passValues {
Model *model = [Model sharedModel];
model.passedText = text2pass;
}
@end

ViewController2.h

#import <UIKit/UIKit.h>
#import "ViewController.h"

@interface ViewController2 : UIViewController {

NSString *passedText;
}

@property (nonatomic)NSString *passedValue;

@property (weak, nonatomic) IBOutlet UILabel *lbl;

- (IBAction)back:(id)sender;

@end

视图控制器2.m

#import "ViewController2.h"

@interface ViewController2 () {
NSString *passedtext;
}
@end
@implementation ViewController2
@synthesize lbl = _lbl;
@synthesize passedValue = _passedValue;
 - (void)viewDidLoad
{

 // do code stuff here
NSLog(@"passedText = %@",passedText);
_lbl.text = passedText;

[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setLbl:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (IBAction)back:(id)sender {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *vc = (ViewController *) [storyboard instantiateViewControllerWithIdentifier:@"welcome"];
[self presentModalViewController:vc animated:YES];
}
@end

模型.h

#import <Foundation/Foundation.h>

@interface Model : NSObject {

NSString *passedText;
}

@property (nonatomic, strong) NSString* passedText;

+ (Model *) sharedModel;

@end

模型.m

#import "Model.h"

@implementation Model

@synthesize passedText = _passedText;

static Model *sharedModel = nil;

+ (Model *) sharedModel {
@synchronized(self){
    if (sharedModel == nil){
        sharedModel = [[self alloc] init];
    }
}
return sharedModel;
}

@end

该项目可以从这里完整下载http://chrisrjones.com/files/KegCop-Test.zip

如果您知道为什么 UILabel 不显示文本字段文本,请告诉我。哦,我非常关注这个 -> http://www.youtube.com/watch?v=ZFGgMPcwYjg&feature=plcp

4

2 回答 2

5

您的寻址和内存管理很简单......关闭。首先,绝对没有理由为此创建一个单例,但这不是重点。

其次,在声明属性时, (atomic, assign) 如果没有另外指定,则默认为,这意味着您的字符串:

@property (nonatomic)NSString *passedValue;

是弱酱,已经成熟,可以立即释放和销毁。声明它copystrongretain

第三,在推送视图控制器中绝对没有引用您的单例,但您似乎相信在不同类中命名相同的对象保留其价值(尤其是在#import'ed 时)。不是这样。您需要引用您的单例并将值拉[Model sharedModel].passedText入该文本字段。

实际上,我将您的示例固定在两行中:

//ViewController2.m
#import "ViewController2.h"

//actually import the singleton for access later
#import "Model.h"

@interface ViewController2 () {
    NSString *passedtext;
}
@end
@implementation ViewController2
@synthesize lbl = _lbl;
@synthesize passedValue = _passedValue;
- (void)viewDidLoad
{

 // do code stuff here
    NSLog(@"passedText = %@",passedText);
    //actually reference the singleton this time
    _lbl.text = [Model sharedModel].passedText;

    [super viewDidLoad];
}
- (void)viewDidUnload
{
    [self setLbl:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}
- (IBAction)back:(id)sender {

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    ViewController *vc = (ViewController *) [storyboard instantiateViewControllerWithIdentifier:@"welcome"];
    [self presentModalViewController:vc animated:YES];
}
@end

这产生了这个:

修复了代码

于 2012-07-10T02:58:12.970 回答
1

我不建议使用 Singleton 作为在应用程序中传递数据的好方法。大多数应用程序都很简单,不需要这种集中访问,而且它通常会造成维护噩梦......但我认为您使用单例的事实对于让您的代码正常工作实际上并不重要。

假设您可以访问 ViewController1 中的数据,在您的情况下是通过 Model 的 Singleton 实例(需要一个更具描述性的名称),那么您所要做的就是在创建和呈现数据时将数据传递给 ViewController2,这完全消除了对 Singleton 的需要。

一旦你创建了控制器,设置你需要的数据,然后呈现视图控制器——这基本上就是你正在做的事情。

至于为什么它不起作用:视图控制器是否被呈现,只是没有正确的数据?或者实际上是否存在呈现控制器的问题?我会在go:ViewController1 的操作中设置一个断点,确保您期望的数据在文本字段中,正确填充模型并且该值被正确地从 ViewController2 中的模型中提取出来。

除非您删除了一些代码,否则看起来您在 ViewController1 中正确填充了 Model 属性,但在 ViewController2 中您引用的是本地 ivar passedText,而不是从模型中提取它。

在单独的说明中,从呈现的模态视图控制器返回的方法通常是关闭该控制器,而不是重新创建初始控制器并将其呈现在顶部。

于 2012-07-10T03:04:11.247 回答