更新 - 找到原因! ...请在下方阅读&建议解决方案:
在创建视频以显示此问题时,我发现为什么会发生这种情况......
在#imports
&之间定义的任何控制/元素在为VC创建新实例时,原始detVC会丢失@implementation DetailViewController
文件中的.m
。
示例:
我正在收录一个重新创建此问题的视频。如图所示,除了UISegmentedControl
&一个UILabel
..这两个都在DetailViewController.m
中定义为:
#import "DetailViewController.h"
UISegmentedControl *sortcontrol;
UILabel *incrementLabel;
@implementation DetailViewController
视频链接 - http://www.youtube.com/watch?v=2ABdK0LkGiA
我认为我们非常接近..等待答案!!
P.S。:我认为这个信息足以引导我们解决方案,但如果需要我也可以共享代码。
EARLIER:
我们的应用程序中有一个detailViewController(detVC),它通常是从UITableViewController“推送”的。
现在我们也正在实施推送通知,每当通知到达时,它会“模态地”呈现相同的detVC,而这反过来可以在任何视图控制器上发生。
它一切正常,直到通过通知发出detVC,而另一个detVC实例已经是活动视图控制器(之前通过TableView推送)。
问题发生在所呈现的detVC被解雇时 - 被推动的detVC'失去了对所有事物的控制 - 它没有指向与之前相同的数据&甚至导航工具栏上的UISegmentedControl
在按任何索引时指向-1
索引!
当我们创建一个单独的detVC实例时,为什么会发生这种情况?为什么它会影响早期的detVC?如何解决/目标C需要在这里学习什么? (仅供参考,我们在项目中使用ARC)
由于
编辑 - 一些代码:
推送时:
ProductDetailViewController *detailViewController = [[ProductDetailViewController alloc] init];
detailViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.serverOffset=serverOffset;
detailViewController.prdctIndex = indexPath.row;
通过通知提交时:
- (void)displaySingleProduct:(NSDictionary*)userInfo{
ProductDetailViewController *onePrdVC = [[ProductDetailViewController alloc] init];
UINavigationController *addNav = [[UINavigationController alloc] initWithRootViewController:onePrdVC];
onePrdVC.justOne=YES;
onePrdVC.onePrdIDtoLoad=[[[userInfo valueForKey:@"prd"] valueForKey:@"id"] intValue];
[self.navigationController presentModalViewController:addNav animated:YES];
}
detVC中有一个Product
类,它从存储在SQLite表中prdctIndex行的值中获取数据。
通过通知解除所提出的detVC后,推送的detVC的Product
类开始指向在呈现的detVC中用于Product
类的行。 viewDidAppear
中没有这样的代码可以改变Product
类。
所以,上面提到的UISegmentedControl
问题&其他一些问题引起了痛苦!基本上,整个detVC行为很奇怪 - 如果我们只是pop& amp;重新推动它!
编辑2
我有更多关于它的信息可能导致原因。
如果我在viewDidLoad
上运行viewDidAppear
,请执行以下操作:
if (!justOne) {
aProduct = [allProducts getProduct:(prdctIndex+1) one:NO];
[self viewDidLoad];
[self populateDetails];
}
推动的detVC重新获得控制权。每个元素/控件都按预期重新开始工作(但不是理想的方式)。因此,很明显,所提出的detVC的单独实例会混淆早期推出的detVC&需要通过viewDidLoad
重新设置所有控件/指针。
可以从这些信息中得出任何有用的结论吗?
答案 0 :(得分:1)
在您的代码中写下:
#import "DetailViewController.h"
UISegmentedControl *sortcontrol;
UILabel *incrementLabel;
@implementation DetailViewController
您没有将这些变量定义为实例变量(ivars),因此它们不是每个实例的个体。定义ivars有三种方法。
1)传统方式,在.h
文件中。
@interface DetailViewController{
UISegmentedControl *sortcontrol;
UILabel *incrementLabel;
}
2)对Objective-C的一些补充增加了对接下来两种方式的支持。就像在.m
文件中声明它们一样。
@implementation DetailViewController{
UISegmentedControl *sortcontrol;
UILabel *incrementLabel;
}
3)如果这些ivars使用属性来公开它们,那么你可以简单地省略它们的明确定义。所以在.h
:
@interface DetailViewController
@property (strong, nonatomic) IBOutlet UISegmentedControl *sortcontrol;
@property (strong, nonatomic) IBOutlet UILabel *incrementLabel;
然后在.m
文件中:
@implementation DetailViewController
@synthesize sortcontrol;
@synthesize incrementLabel;
答案 1 :(得分:0)
您是从NIB加载视图控制器吗?如果是这样,则可能每次都使用视图控制器的相同实例。您可以在viewDidLoad中记录视图控制器的地址,看看是否是这种情况。
答案 2 :(得分:0)
如果同一个类的两个实例相互干扰,则强烈建议您不要将所有状态存储在实例变量中。我怀疑ProductDetailViewController
中的某些内容将其状态存储在全局或类数据中,并且您的问题存在于那里。
你有可能做了一些愚蠢的事情,比如让ProductDetailViewController
成为一个强迫的单身人士(覆盖+alloc
,你几乎从不这样做),但一般人都记得他们什么时候做过。
切勿直接致电viewDidLoad
。这只是系统调用。 (我知道你只是在测试,但不要把它留在那里。)
但是你在[super viewDidAppear:animated]
打电话给viewDidAppear:
吗?你必须用那种方法调用你的超类。
答案 3 :(得分:0)
这实际上取决于您的应用程序架构的创建方式。如果您使用的是基于TabBarController的应用程序,here是正确的方法。