【问题标题】:Data is not persisting in multiple instances of the same object (iOS)数据不会保留在同一对象的多个实例中 (iOS)
【发布时间】:2010-11-12 23:24:10
【问题描述】:

我在创建的对象的多个实例中持久存在数据时遇到问题。

我有一个扩展 UIViewController 的类“IconViewController”,我将信息传递给它,例如它应该使用的图像的名称:

//IconViewController.h @interface AppIconViewController : UIViewController { NSString *imageName; } @property (nonatomic, retain) NSString *imageName; - (void) doSomething; //IconViewController.m @implementation AppIconViewController @synthesize imageName; NSNumber *iconWidth; - (void)loadView { [super loadView]; UIImageView *iconImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]]; iconWidth = [NSNumber numberWithFloat:iconImage.bounds.size.width]; [iconImage release]; NSLog(@"iconWidth: %f", [iconWidth floatValue]); } - (void) doSomething { NSLog(@"iconWidth: %f", [iconWidth floatValue]); }

在另一个视图控制器中,我正在实例化这些 IconViewControllers 的几个实例并将不同大小的图像传递给它们:

AppIconViewController *appIcon1 = [[AppIconViewController alloc] initWithNibName:nil bundle:nil]; appIcon1.imageName = @"Image65PXWide.png"; [self.view addSubview:appIcon1.view]; AppIconViewController *appIcon2 = [[AppIconViewController alloc] initWithNibName:nil bundle:nil]; appIcon2.imageName = @"Image105PXWide.png"; [self.view addSubview:appIcon2.view];

好的,奇怪的是,当我创建这些时,我得到的日志是准确的......appIcon1 记录“iconWidth:65.0”和 appIcon2 记录“iconWidth:105.0”。但是当我打电话时:

[appIcon1 doSomething];

...我的日志是“iconWidth:105.0”。

为什么第一个实例中的数据反映了第二个实例中的数据?我错过了什么?

编辑:
我知道,如果我在标题中声明 iconWidth 并将其综合为属性,它将起作用。所以我想知道的是如何让它的私有版本持续存在。因为我尝试使用以下方式保留 NSNumber:

iconWidth = [[NSNumber numberWithFloat:iconImage.bounds.size.width] 保留];

...它仍然无法正常工作。一定要合成公开吗?

编辑 #2:
好的,所以我发现一旦我在标题中声明了 iconWidth,它就可以正常工作,而且我不必合成它,因此它保持私有。不知道为什么如果在实现文件中声明它到底不起作用 - 有没有人知道为什么以及是否有任何目的在实现顶部而不是在标题中声明变量?现在只是好奇比什么都重要。

【问题讨论】:

    标签: iphone objective-c ios


    【解决方案1】:

    合成不会使任何东西成为私有的。它只是根据声明的属性生成 getter/setter 方法。

    通过在实现中放置iconWidth,在任何方法之外,它本质上是一个类级别的变量。所以它会被最后一个写入它的东西覆盖。你已经在接口中声明了imageName,那么为什么不把iconWidth也放在那里(实例变量默认是私有的)?

    【讨论】:

      【解决方案2】:

      在您的方法 doSomething 中,您假设 iconWidth 设置正确。

      然而,iconWidth 在 loadView 方法中被创建为一个 autorelease 对象,所以当 loadView 完成时,主循环将释放 iconWidth 并且你得到随机值。

      要解决此问题,您必须保留 iconWidth 以便在其他方法中使用它

      iconWidth = [[NSNumber numberWithFloat:iconImage.bounds.size.width] retain];
      

      作为一般规则,不以 init 开头的方法将返回 autorelease 对象,因此您必须注意如何实例化对象以及是否需要对其调用 retain。

      【讨论】:

      • 感谢您的回答!我刚刚编辑了我的帖子,说如果我像你刚才展示的那样保留它,它仍然不起作用,这很奇怪。我让它工作的唯一方法是将它合成为一个属性,但我想知道是否可以将它保密。
      猜你喜欢
      • 1970-01-01
      • 2012-01-13
      • 2011-02-12
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      • 2022-12-10
      相关资源
      最近更新 更多