0

我是 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 没有改变。为什么?

4

1 回答 1

1

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

前:

MasterViewController.str -> 1234 <- DetailViewController.detailItem

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

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

您在这里要做的是使用委托模式正确地通知 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;
}
于 2013-08-17T19:26:05.947 回答