如何增加 NSTimer 标签中的时间?
我是一名初出茅庐的 iPhone 开发者,所以请对我宽容一些。
我正在尝试开发一个简单应用程序,它将显示时间,然后每秒勾选一次。我觉得我在内存管理方面错过了一些东西,但我的技能太新了,无法真正知道我错过了什么。
我正在创建一个直接到主窗口的标签(非常简单的应用程序),并尝试通过 NSTimer
更新标签。这是我的代码,它仍然有点混乱。
@synthesize label, theDate;
@synthesize window;
- (void)tick
{
theDate = [[NSDateFormatter alloc] init];
[theDate setDateFormat:@"hh:mm:ss"];
NSString* currentTime = [theDate stringFromDate:[NSDate date]];
label.text = [[NSString alloc] initWithFormat:@"%d",currentTime];
[currentTime release];
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect rect = CGRectMake(10, 200, 300, 20);
label = [[UILabel alloc] initWithFrame:rect];
label.textAlignment = UITextAlignmentCenter;
[self.window addSubview:label];
[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(tick)
userInfo:nil
repeats:YES];
[self.window makeKeyAndVisible];
return YES;
}
@synthesize
的 ivars 是 .h 文件中的 @property
,并且 ivars 在 dealloc 中释放。
谢谢!
I'm a fledgling iPhone developer, so be easy on me.
I'm trying to develop a simple app that will show the time and then tick every second. I feel like I'm missing something here with memory management, but my skills are too fresh to really know what I'm missing.
I'm creating a label straight to the main window (really simple app) and trying to update the label through and NSTimer
. Here is my bit of code, it's still a little messy.
@synthesize label, theDate;
@synthesize window;
- (void)tick
{
theDate = [[NSDateFormatter alloc] init];
[theDate setDateFormat:@"hh:mm:ss"];
NSString* currentTime = [theDate stringFromDate:[NSDate date]];
label.text = [[NSString alloc] initWithFormat:@"%d",currentTime];
[currentTime release];
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect rect = CGRectMake(10, 200, 300, 20);
label = [[UILabel alloc] initWithFrame:rect];
label.textAlignment = UITextAlignmentCenter;
[self.window addSubview:label];
[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(tick)
userInfo:nil
repeats:YES];
[self.window makeKeyAndVisible];
return YES;
}
The @synthesize
'd ivars are @property
s in the .h file and the ivars get released in dealloc.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这里存在许多内存问题:
theDate
但没有释放它,因此它正在泄漏。currentTime
,因此您可能会在自动释放池中看到崩溃。label.text
的值,但没有释放它; label.text 是保留属性,在这种情况下,您会通过双重保留来泄漏该字符串,或者 label.text 不是保留属性,在这种情况下,您不会通过释放它来泄漏该字符串(最后一个除外) ,在 dealloc 中)我强烈建议您阅读 Apple 的内存管理指南。
此外,与内存问题无关,您正在使用
%d
尝试显示字符串而不是%@
,因此您将获得指针地址的数值而不是字符串的内容。You have a number of memory problems here:
theDate
but not releasing it, so it's leaking.currentTime
despite not having an owning reference, so you'll likely see crashes in the autorelease pool.label.text
but not releasing it; either label.text is a retaining property, in which case you are leaking that string by double-retaining it, or label.text is not retaining, in which case you are leaking the string by never releasing it (except for the very last one, in dealloc)I'd strongly suggest you read Apple's memory management guide.
Also, unrelated to the memory issues, you are using
%d
to try to show a string instead of%@
, so you'll get the numeric value of the pointer address rather than the contents of the string.您不应该释放 currentTime。您没有通过名称中带有“new”、“alloc”、“retain”或“create”的东西获得它,因此您不拥有它。您正在做的是分配一个不相关的字符串并将其提供给 label.text,然后无法释放它。建议您将这三行替换为:
如果 UILabel 想要保留该字符串,则由 UILabel 来保留该字符串(我希望它会,但这是一个实现细节,无论如何都与我们无关),并且您不拥有因此可以让它在自动释放池中过期。
在相同的方法中,您还创建了一个名为“theDate”的 NSFormatter 并且无法释放它。实际上,您似乎对 getter 和 setter 有点困惑,这并不奇怪,因为这里有一些 Objective-C 的传统。如果您执行以下操作:
那么您将按照正常的 C '=' 运算符,直接将指定的值复制到变量中。那里没有 Objective-C 的魔力。您是否以及如何申报您的财产(很大程度上,请参阅脚注)无关紧要。
如果您类似:
那么编译器的行为将与您编写的完全一样:
因此您将获得一个方法调用,并且将使用您的实际设置器。 setter 将执行您通过 @property/@synthesize 告诉它的任何操作(即保留、复制或分配)。因此,在 dealloc 中,您往往会看到:
或:
与“retain”属性具有相同的整体效果(尽管后者实际上释放了原始属性,然后保留“nil”,任何发送给“nil”的消息都没有效果)。
同样的混乱可能会影响您对标签的使用,但您目前所做的事情在技术上是正确的。如果您使用“self.label =”而不是直接赋值,那么您需要传递一个自动释放的对象或您知道如何稍后释放的对象。
另外:非常值得查看 NSZombies 和 Instruments 中的 Leaks 工具;前者将帮助您了解何时以及如何访问已释放的对象,后者将帮助您发现何时泄漏内存。 Guard Malloc 对于前者也很有用,但运行时开销要大得多,我不确定它目前在 iOS 上的工作情况如何。
(脚注:在现代 64 位和 ARM 运行时中,实例变量是动态的,其实际效果是您可以纯粹通过 @property 和 @synthesize 声明它们,而无需以其他方式将它们放入 @interface 声明中;如果您这样做,那么显然@property的存在与否会影响直接访问是否有效)
You shouldn't release currentTime. You didn't get hold of it through something with 'new', 'alloc', 'retain' or 'create' in the name, so you don't own it. What you are doing is allocating an unrelated string and giving it to label.text, then failing to release that. Suggest you replace those three lines with just:
It's up to the UILabel to retain the string if it wants to keep it (I expect it will, but it's an implementation detail and none of our business either way), and you don't own it so can just leave it to expire on the autorelease pool.
In the same method you also create an NSFormatter called 'theDate' and fail to release it. Actually, you seem to be a bit confused about getters and setters, which isn't surprising since there's a bit of Objective-C heritage at play here. If you do something like:
Then you'll directly copy the value specified into the variable, as per the normal C '=' operator. There's no Objective-C magic there. Whether and how you've declared your property is (largely, see foot note) irrelevant.
If you something like:
Then the compiler will act exactly as if you'd written:
So you get a method call and your actual setter will be used. The setter will do whatever you told it to via the @property/@synthesize (ie, retain, copy or assign). Hence, at dealloc you tend to see either:
Or:
Which have the same overall effect with 'retain' properties (though the latter actually releases the original then retains 'nil', any message to 'nil' having no effect).
The same confusion possibly affects your use of label, but what you're doing at the minute is technically correct. If you'd used 'self.label =' instead of the direct assignment then you'd want to pass an autoreleased object or one that you know how to release later on.
Addition: it's well worth checking out NSZombies and the Leaks tool in Instruments; the former will help you find out when and how you're accessing deallocated objects, the latter will help you spot when you're leaking memory. Guard Malloc is also useful for the former but carries a much larger runtime overhead and I'm not sure how well it works with iOS at present.
(foot note: in the modern 64 bit and ARM runtimes, instance variables are dynamic with the practical effect that you can declare them purely via @property and @synthesize without otherwise putting them in the @interface declaration; if you're doing that then obviously the presence or absence of the @property will affect whether direct access works)
用这个替换你的tick函数:-
{
theDate = [[NSDateFormatter alloc] init];
[theDate setDateFormat:@"hh:mm:ss"];
NSString* currentTime = [theDate stringFromDate:[NSDate 日期]];
标签.text = 当前时间;
}
Replace your tick function with this one:-
{
theDate = [[NSDateFormatter alloc] init];
[theDate setDateFormat:@"hh:mm:ss"];
NSString* currentTime = [theDate stringFromDate:[NSDate date]];
label.text = currentTime;
}