为什么ViewController Class的单​​独实例会影响以前的实例?

时间:2012-01-15 18:10:58

标签: iphone objective-c ios uiviewcontroller

更新 - 找到原因! ...请在下方阅读&建议解决方案:

在创建视频以显示此问题时,我发现为什么会发生这种情况......

#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重新设置所有控件/指针。

可以从这些信息中得出任何有用的结论吗?

4 个答案:

答案 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是正确的方法。