数据不会持久存储在同一对象的多个实例中(iOS)

时间:2010-11-12 23:24:10

标签: iphone objective-c ios

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

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


//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] retain];

......它仍然不起作用。是否需要合成和公开?

编辑#2:
好吧,所以我想到,一旦我在标题中声明了iconWidth,它就可以正常工作,而且我不需要合成它,所以它保持私密性。不确定为什么如果在实现文件中声明它将无法正常工作 - 是否有人有任何洞察为什么以及在实现顶部但不在标题中声明变量的任何目的?现在只是好奇。

2 个答案:

答案 0 :(得分:0)

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

但是,在loadView方法中将iconWidth创建为自动释放对象,因此当loadView完成时,主循环将释放iconWidth,并且您将获得随机值。

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

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

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

答案 1 :(得分:0)

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

通过在实现中放置iconWidth,在任何方法之外,它本质上是一个类级变量。因此它会被写入它的最后一件事覆盖。您已经在界面中声明了imageName,那么为什么不将iconWidth放在那里(默认情况下实例变量是私有的)?