Cocoa:CALayer:视图的连续重绘不断增加分配的内存
我有内存分配问题(无论如何都不是泄漏)。
我的程序有一个自定义 Window
和一个自定义 View
,其中包含一个 TextField
、一个 ImageView
和一个 Shadow
。 假设我每 1 秒使用 [myTextField setStringValue:@"actual string"]
以编程方式更新 TextField
的值。
显然,每次 TextField 发生更改时,视图都会重新绘制。
如果我查看活动监视器,我会发现每次更新 TextField 并因此重新绘制视图时,分配的内存都会增加。 ImageView 不应该改变。 如果我用 (请参阅更新 4。)setStringValue
注释该行,程序运行时根本不会增加内存。
请注意,Instruments
不会报告内存泄漏或未释放的对象,并且 View 被自动释放。
什么会导致这种情况?
更新
我发布了实际代码的简化版本:
.h
CustomTextField *myTextField;
int level;
@interface Dummy : NSObject {
NSString *level_string;
NSTimer *timer;
}
@end
.m
@implementation Dummy
- (void)awakeFromNib
{
// ...
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(changestring:)
userInfo:nil
repeats:YES];
// ...
}
-(void)changestring:(NSTimer *)timer
{
level++;
level_string = [[NSString alloc] initWithFormat:@"%i",level];
[myTextField setStringValue:level_string];
[level_string release];
}
其中 CustomTextField
是一个 NSTextField
类。
我不知道我要添加的内容是否重要,无论如何,自定义窗口、自定义视图和自定义文本字段都是在代码中以编程方式定义和 init
的,并且它们不会在界面中实例化建设者。
更新2
我错了!即使我评论 setStringValue
内存仍然增加..少很多,但它仍然增加.. 奇怪的事实是,无论如何,仪器报告的“活动对象”的大小保持不变,并且没有报告泄漏。
怎么了?
更新3
我刚刚使用了Instruments令人惊叹的heapshots功能和这个 就是结果。
我在活动监视器中看到的内存增加(几分钟后达到数千字节的量级)来自哪里?
更新4
我想我已经找到了导致问题的原因,但我无法解决它。
View 有一个 TextField、一个 ImageView 和一个 Shadow。为了使它们正确显示在屏幕上而不会出现故障,我添加了 [view setWantsLayer:YES]
。 如果我注释掉这一行,内存分配问题肯定就解决了。
现在,只要我需要使用那个命令,我该怎么办?我应该发布一些与核心动画相关的东西吗?请注意,与核心动画相关的唯一一个命令是上面的命令。
I have a problem of memory allocation (not leak anyway).
My program has a custom Window
with a custom View
containing a TextField
, an ImageView
and a Shadow
.
Let's say that every 1 second I programmatically update the value of the TextField
using [myTextField setStringValue:@"actual string"]
.
Obviously, every time the TextField get changed, the view is redrawn.
If I look in Activity Monitor I see that every time the TextField is updated, and therefore the view is redrawn, the allocated memory increases. The ImageView isn't supposed to change.If I comment the line with (See Update 4.)setStringValue
, the program runs without increasing memory at all.
Note that Instruments
does not report memory leak or unreleased object and View is autorelease
'd.
What can cause this?
UPDATE
I post a simplified version of the actual code:
.h
CustomTextField *myTextField;
int level;
@interface Dummy : NSObject {
NSString *level_string;
NSTimer *timer;
}
@end
.m
@implementation Dummy
- (void)awakeFromNib
{
// ...
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(changestring:)
userInfo:nil
repeats:YES];
// ...
}
-(void)changestring:(NSTimer *)timer
{
level++;
level_string = [[NSString alloc] initWithFormat:@"%i",level];
[myTextField setStringValue:level_string];
[level_string release];
}
Where CustomTextField
is a NSTextField
class.
I don't know if what I'm going to add is important, anyway the custom window, the custom view and the custom textfield are defined and init
programmatically in the code and they are not instantiated in interface builder.
UPDATE 2
I was wrong! Even if I comment setStringValue
the memory still increases..a lot less, but it still increases..
The strange fact is that Instruments, in any case, reports a size of "Living Object" which remains constant and no leak is reported.
What is happening?
UPDATE 3
I have just used the amazing heapshots feature of Instruments and this is the result.
The memory increase that I see in activity monitor (which is of the order of thousands of kilobytes after few minutes) where does come from?
UPDATE 4
I think I have found what is causing the problem but I'm not able to solve it.
The View has a TextField, an ImageView and a Shadow. To make them appearing correctly on screen without glitches I have added [view setWantsLayer:YES]
.
If I comment this line, the memory allocation problem is definitely solved.
Now, as long as I need to use that command, how can I do? Am I supposed to release something related with Core Animation? Note that the only one command related with Core Animation is the above one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请观看 WWDC10 会议视频的会议 311 - 使用仪器进行高级内存分析。如何下载这些视频可以在此处找到。
您可能会看到废弃的内存或正在进行一些缓存。如果在模拟器中触发内存不足警告,会发生什么情况?内存下降了?
还可以尝试使用 Instruments 的堆快照功能:进行堆快照、更新字符串并显示已创建的对象。在上面提到的会话视频中演示了该过程。
编辑:我忘记了什么:如果您无法弄清楚发生了什么,并且您可以显示增加内存分配的行为而不释放它,如果在简单的示例应用程序中触发低内存警告,请在 Apple 的 bugreporter 发送此示例项目和 Instruments 跟踪文件以显示正在发生的情况。
EDIT2:我错误地认为这个问题是在 Mac OS X 上。同样的原理也适用于 Mac OS X 应用程序。 Cocoa 中的内存管理在 iPhone 和 Mac 上几乎相同。最大的区别是 Mac 上有垃圾收集功能。当然,在 Mac 上没有内存不足警告,因此请忽略它。
Have a look at session 311 - Advanced Memory Analysis with Instruments of WWDC10 session videos. How to download these videos can be found here.
It could be that you see abandoned memory or that there is some caching going on. What is happening if you trigger a low memory warning in the simulator? Goes the memory down?
Also try using the heapshot feature of Instruments: make a heapshot, update the string and show which objects have been created. In the session video mentioned above the procedure is demonstrated.
EDIT: What I forgot: if you cannot figure out what is going on and you can show this behavior of increasing memory allocation without releasing it if a low memory warning is triggered in a simple example application, file a bug at Apple's bugreporter sending in this sample project and an Instruments trace file to show what is going on.
EDIT2: I was wrong assuming that this problem was on Mac OS X. The same principles apply for a Mac OS X application as well. Memory management in Cocoa is almost the same on the iPhone and the Mac. The biggest difference is that on the Mac there is garbage collection available. Of course on the Mac there are no low memory warnings, so leave that out.
CustomTextField 中的 setStringValue: 有何作用?我的猜测是您保留传递的字符串而不释放设置器中的旧值。
What setStringValue: in CustomTextField does? My guess is that you're retaining passed string without releasing old value in your setter.