财产不更新

时间:2013-08-17 18:56:13

标签: iphone ios objective-c

我是iOs编程的初学者。我有一些问题。我有MasterViewController,代码如下

#import "MasterViewController.h"

#import "DetailViewController.h"

@interface MasterViewController () {

}

@property (strong, nonatomic) NSString *str;
@end

@implementation MasterViewController

- (void)awakeFromNib
{
    [super awakeFromNib];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.str = @"1234";
}

我将属性“str”发送到DetailViewController。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSString *object = self.str;
        [[segue destinationViewController] setDetailItem:object];
    }
}

之后,我改变了str

#import "DetailViewController.h"

@interface DetailViewController ()
@end

@implementation DetailViewController

- (void)setDetailItem:(id)newDetailItem
{
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;


    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.detailItem = @"1233";
} 

之后,我回到MasterViewController但是str没有改变。为什么呢?

1 个答案:

答案 0 :(得分:1)

问题在于,您只是在detailItem中更改DetailViewController属性引用的对象,而不是更改对象本身的值。当您在self.detailItem方法中设置viewDidLoad时,str属性MasterViewController将继续指向原始字符串:

在:

MasterViewController.str -> 1234 <- DetailViewController.detailItem

然后你做self.detailItem = 1233。它不会更改字符串本身的值,只是使detailItem指向一个新字符串。看下面的图表,它会移动指向DetailViewController的箭头,而不是更改“1234”本身的内容:

MasterViewController.str -> 1234
                            1233 <- DetailViewController.detailItem

您要在此处执行的操作是使用delegate模式正确通知MasterViewController详细控制器中的更改,并授予其访问新值的权限。

DetailViewController.h:

// declare the delegate protocol
@class DetailViewController;
@protocol DetailViewControllerDelegate <NSObject>
    -(void)detailViewControllerChangedDetailItem:(DetailViewController *)detailController;
@end

@interface DetailViewController
// add a property for the delegate
@property (nonatomic, copy) NSString *detailItem;
@property (nonatomic, weak) id <DetailViewControllerDelegate> delegate;
@end

DetailViewController.m:

- (void)setDetailItem:(id)newDetailItem
{
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;
        // notify the delegate whenever the detailItem changes
        [self.delegate detailViewControllerChangedDetailItem:self];
   }
}

MasterViewController.m:

// mark this as implementing the delegate protocol
@interface MasterViewController () <DetailViewControllerDelegate> {
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSString *object = self.str;
        // wire up the delegate connection
        [[segue destinationViewController] setDelegate:self];
        // now whenever detailItem changes in the DetailViewController,
        // it will notify its delegate (the master VC)
        [[segue destinationViewController] setDetailItem:object];
    }
}

// implement the delegate method
-(void)detailViewControllerChangedDetailItem:(DetailViewController *)detailController
{
    // now you can get a copy of the new detailItem value 
    // and do whatever you want with it.
    self.str = detailController.detailItem;
}