我是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没有改变。为什么呢?
答案 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;
}