简体   繁体   中英

Property don't update

I beginner in iOs programming. I have some problem. I have MasterViewController, code below

#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";
}

and I send property "str" to DetailViewController.

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

after, I change 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";
} 

after, I come back to MasterViewController but str don't change. Why?

The problem is that you're just changing which object the detailItem property refers to in DetailViewController , rather than changing the value of the object itself. When you set self.detailItem in the viewDidLoad method, the str property MasterViewController will continue to point to the original string:

Before:

MasterViewController.str -> 1234 <- DetailViewController.detailItem

Then you do self.detailItem = 1233 . It doesn't change the value of the strings themselves, but just makes detailItem point to a new string. Looking at the graph below, it moves the arrow pointing from DetailViewController rather than changing the content of "1234" itself:

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

What you want to do here is use the delegate pattern to properly notify the MasterViewController of changes in the detail controller and give it access to the new value.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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