4

场景 1:对于 UIViewController,最好 (1) 为我在外部的 1 个或 2 个函数中再次访问的 UIView 创建一个 ivar loadView?或者,(2)我应该只是标记它,loadView然后- (UIView *)viewWithTag:(NSInteger)tag在其他功能中再次使用它?我猜选项 1 将内存增加了指针的大小,因此是 32/64 位,并创建访问器方法(假设我声明@property& @synthesize),然后需要释放 ivardealloc并将其设置为nilin viewDidUnload...选项 2 节省内存,设置代码更少,但需要一些处理时间和一些额外的代码来通过标签查找视图。我对这一切是否正确?

在这种情况下,最好使用 ivar,但我不确定。

场景 2:对于具有 5 个子视图的 UIView 的自定义子类怎么办?请记住,在给定时间我将在内存中拥有大约 30 个此自定义子类的实例(它们将是tableViewCells 的子视图),我应该为子视图使用 5 个 ivars,还是应该将它们全部标记?

在这种情况下,我认为通过标记它们所节省的内存将值得使用- (UIView *)viewWithTag:(NSInteger)tag.

想法?

谢谢!

马特

4

3 回答 3

5

考虑一下,每个视图都由 CALayer 支持。IIRC,视图大约 44 个字节(加上 foo),层大约 44 个字节(乘以 3,因为有一个表示树和渲染树),并且执行任何渲染的层都由位图上下文支持。

或者,为了更直接的比较:每个指针消耗与单个像素一样多的内存。

我只在标签让我的生活更轻松的地方使用标签:

  • 笔尖中有很多相似的视图(一堆按钮,每个选择不同的颜色)。我可以连接一堆插座,但是代码必须处理一堆 ivars 而不是一些算术)。
  • 许多具有类似功能的子视图(例如,滚动视图中的“页面”,或类似 UITableView 的容器中的类似单元格的视图)。我可以在数组中跟踪它们,但我今天感觉很懒。
  • 每当我需要一个视图来存储一个额外的整数(例如页码)时。还有很多其他方法(子类化、“关联对象”、将值粘贴在layer.style...中)。这一般与前两个地方有关。

另外,请记住,[v viewWithTag:tag]可以返回v,任何子视图,任何子视图的子视图......考虑一个类 FooView,它有一个带有标签 1 的“内容视图”和一个带有标签 2 的“工具栏视图”:

FooView * f1 = ...;
FooView * f2 = ...;
[f1.contentView addSubview:f2];
NSLog(@"%@ %@", f1.toolbarView, f2.toolbarView);

它打印什么?好吧,它们都可以是f2的工具栏!

是的,Apple 可以使搜索更明智(它可以继续搜索,直到找到深度最小的匹配,或者使用迭代加深深度优先搜索),但我假设它执行简单的深度优先搜索,除非文档另有说法。

于 2010-09-27T01:54:27.060 回答
5

考虑到内存使用的差异可以忽略不计(除非您将拥有 100 个这样的视图,在这种情况下,您可能想研究如何重用其中一些视图),您可能应该考虑什么会使您的代码更多可读和可维护。我个人认为使用 ivar 会更具可读性,但对于您的特定情况,使用标签也可能更具可读性。

在编写代码时,我总是试着想一两年后将要阅读代码的人。这个人可能是我,也可能是其他人,但无论哪种方式,我都知道那个人会喜欢可读的代码。他们不太可能感谢我在至少具有 128 MB RAM 的设备上节省 1k 内存。

于 2010-09-27T01:37:27.093 回答
4

我想你问错问题了。

在我看来,无论是存储 5 个指针所需的内存,还是使用查找 5 个视图所需的时间viewWithTag:,在总体方案中都可以忽略不计。

选择您找到的任何解决方案,使您的代码更易于编写、理解和维护。

万一时间/内存使用的实际分析表明您选择的解决方案存在问题,请考虑其他选项。其他任何事情都是过早的优化。

于 2010-09-27T01:36:51.270 回答