2012-07-10 58 views
-8

好的,所以這是我昨晚問的一個問題的擴展。我對使用各種技術在視圖控制器之間傳遞數據的方式有了更加清楚的認識。我想去MVC路線,創建一個Singleton類似乎是最接近MVC的概念。Obj-C - 如何使用單例在視圖控制器之間傳遞數據?

基本上我創建了一個簡單的應用程序與兩個視圖控制器和一個單例類。我正在嘗試將文本字段的值傳遞給UILabel。無論出於何種原因,它都不起作用。這是我的代碼看起來像。

ViewController.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 

ViewController.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 

ViewController2.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 

Model.h

#import <Foundation/Foundation.h> 

@interface Model : NSObject { 

NSString *passedText; 
} 

@property (nonatomic, strong) NSString* passedText; 

+ (Model *) sharedModel; 

@end 

Model.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

回答

5

你的尋址和內存管理是簡單的...關閉。首先,完全沒有理由爲此創建一個單例,但這不在這裏。

其次,聲明屬性時,(原子,分配),默認爲如果不是另有說明,這意味着你的字符串:

薄弱醬,成熟的釋放和銷燬,片刻通知。聲明它copy,strongretain。第三,在推送的視圖控制器中絕對沒有提到你的單例,但你似乎相信在不同類中被命名爲相同的對象保留它們的值(尤其是當#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 

其中產量如下:

Fixed the code

1

我不會建議使用一個Singleton作爲傳遞數據的好方法圍繞您的應用程序大多數應用程序很簡單,這種中央訪問不是必需的,它通常會產生維護噩夢...但我不認爲你使用Singleton的事實對於讓你的代碼正常運行非常重要。

假設你有權訪問ViewController1中的數據,在你的案例中通過Model的Singleton實例(需要更多描述性名稱),那麼你所要做的就是在創建ViewController2時將數據傳遞給它並提交,完全消除了Singleton的需要。

一旦你創建了控制器,設置你需要的數據,然後呈現視圖控制器 - 這基本上是你在做什麼。

至於爲什麼它不工作:視圖控制器被呈現,只是沒有正確的數據?或者實際上是否存在一個提交控制器的問題?我將在ViewController1的go:操作中設置一個斷點,確保您期望的數據位於文本字段中,正確填充模型並且該值已正確從ViewController2中的模型中拉出。

除非你刪除了一些代碼,否則它看起來像你在ViewController1中正確地填充了Model屬性,但是在ViewController2中你引用了一個本地ivar passedText而不是將它從模型中拉出來。

另一方面,從現有的模態視圖控制器返回的方法通常是關閉該控制器,而不是重新創建初始控制器並將其呈現在頂部。

相關問題