我对保留我的属性和内存管理方面的方式感兴趣。这是一个简单的应用程序,它编辑存储在表中的类的信息。有3个ViewControllers。
目前这是如何构建的,你怎么看?
ListViewController
@property(nonatomic,retain)NSMutableArray * pools;
@property(nonatomic,retain)PoolFacilityEditController * childController;
要向表中添加新的类实例,请单击运行此方法的添加按钮。
//Loads up the editPoolFacility controller to add a new pool
- (void)添加{
PoolFacilityEditController *editController = self.childController;
PoolFacility *aPoolFacility = [[PoolFacility alloc] init];
[self.pools addObject:aPoolFacility];
[aPoolFacility release];
editController.thePoolFacility = aPoolFacility;
editController.pools = self.pools;
[self.navigationController pushViewController:editController animated:YES];
}
现在加载下一个控制器,这是它有趣的实例变量。明智与否我选择将池分配给新控制器而不是保留。我不想不必要地保留。
详细信息视图
@property (nonatomic, assign) PoolFacility *thePoolFacility; (assigned in the above add method)
@property(nonatomic,assign)NSMutableArray * pools; (也在添加方法中分配)
详细视图有一个执行以下操作的方法..
- (void)viewWillAppear:(BOOL)animated {
//Pass the copy onto the child controller
if (self.childController.thePoolFacility != self.thePoolFacility) {
self.childController.thePoolFacility = self.thePoolFacility;
}
}
将池传递到详细编辑控制器,以便它知道正在编辑的池。
现在,用户点击池信息的单个位(例如名称),弹出详细视图控制器。它允许编辑各个属性。
有趣的属性看起来像这样:
@property (nonatomic, retain) PoolFacility *thePoolFacilityCopy;
@property(nonatomic,assign)PoolFacility * thePoolFacility;
如果用户更改了值然后想要取消,它会创建一个要编辑的副本。如果用户按下保存,则会将副本中的值复制到非副本中。
- (void)viewWillAppear:(BOOL)animated {
PoolFacility *poolCopy = [self.thePoolFacility copy];
self.thePoolFacilityCopy = poolCopy;
[poolCopy release];
}
如果按下保存或取消,则会弹出视图。
然后我们回到显示所有字段的中间视图。
现在,如果用户按下了save,我只需弹出viewcontroller,然后返回列表视图。或者如果用户按下取消,我运行此方法。
-(void)cancel {
[self.pools removeObject:self.thePoolFacility];
[self.navigationController popViewControllerAnimated:YES];
}
总结
我在不同的视图控制器中分配属性而不是保留它。
此外,我的视图控制器只加载一次,并且在“消失”时不会被释放
我希望这有一定道理!我的问题是......这是一个很好的方法吗?
谢谢,
丹
答案 0 :(得分:2)
我在这里没有看到具体的问题,所以我只会做一些一般性的批评。
在iPhone OS中,取消按钮在用于添加新项目的对话框中很常见,但在编辑对话框中则更少。事实上,我能想到的编辑对话框上的取消按钮的唯一示例是在Clock应用程序的Alarm面板中。因此,不要担心复制PoolFacility并在保存时将更改复制回来;只需使“取消”按钮对新对象可见(或使用“废纸篓”图标 - 取消新池并删除现有池实际上与现在设计的方式相同)。
正如你现在所拥有的那样,在错误的时间没有对象被解除分配的危险。但是,如果您更改了存储方法 - 例如,让应用程序懒洋洋地从磁盘加载PoolFacility对象 - 它会回来咬你。今天写得恰到好处,你明天就会挽救自己的痛苦。正确的方法是使thePoolFacility成为保留属性并在dealloc方法中释放它。 (如果你按照当前的方式继续管理池列表,你应该用它做同样的事情。)
说到这一点,您不会显示现有的PoolFacility对象是如何加载的。他们来自哪里?如果正在进行某种类型的数据库访问,您可能会发现在创建,更新或删除对象时让PoolFacility发送通知,然后根据需要观察并响应相应的通知会很有帮助。我编写的所有存储用户数据的应用程序都采用这种方法;我发现它非常方便灵活。
由于只有一个池列表,并且多个控制器需要它,因此将它存储在您的应用程序委托中而不是传递它并不遗憾。更好的是,编写一个管理列表的FacilityList单例对象。这可以让您从控制器中获取大量逻辑。通常,除了与屏幕交互的内容外,您应该将所有内容都放入模型中。这意味着,当Apple制作iTablet或发布Apple TV SDK时 - 或者当您决定制作Mac版本或重做用户界面时 - 您可以尽可能多地使用未经修改的应用程序。