MyC*_*ner 33 iphone memory-leaks memory-management objective-c nstimer
有没有人知道何时是停止在UIViewController内部保持引用的NSTimer的最佳时间,以避免在定时器和控制器之间保留周期?
这是更详细的问题:我在UIViewController中有一个NSTimer.
在视图控制器的ViewDidLoad期间,我启动计时器:
statusTimer = [NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector(updateStatus) userInfo: nil repeats: YES];
Run Code Online (Sandbox Code Playgroud)
以上导致计时器保持对视图控制器的引用.
现在我想释放我的控制器(例如父控制器释放它)
问题是:我可以在哪里调用[statusTimer invalidate]来强制定时器释放对控制器的引用?
我尝试将它放在ViewDidUnload中,但是在视图收到内存警告之前不会被触发,所以不是一个好地方.我尝试了dealloc,但只要计时器还活着(鸡蛋和鸡蛋问题),dealloc就永远不会被调用.
有什么好建议吗?
Jer*_*man 21
您可以通过以下方式避免保留周期:例如,将计时器瞄准StatusUpdate对象,该对象保存对控制器的非保留(弱)引用,或者通过StatusUpdater控制器指针初始化,保持弱引用为此,并为您设置计时器.
您可以让视图-willMoveToWindow:在目标窗口nil(应该处理-viewDidDisappear:您提供的反例)以及其中时停止计时器-viewDidDisappear:.这意味着您的视图将重新回到您的控制器中; 你可以通过向控制器发送-view:willMoveToWindow:信息或发布通知来避免进入计时器,如果你愿意的话.
据推测,您是导致视图从窗口中移除的那个,因此您可以添加一行来停止计时器以及驱逐视图的线.
您可以使用非重复计时器.一旦它发射它将立即失效.然后,您可以在回调中测试是否应创建新的非重复计时器,如果是,则创建它.然后,不需要的保留周期将仅保持定时器和控制器对,直到下一个发火日期.只需1秒的开火日期,您就不必担心了.
每个建议,但第一个是与保留周期一起生活并在适当的时间打破它的方式.第一个建议实际上避免了保留周期.
解决它的一种方法是让NStimer保持对你的UIViewController的弱引用.我创建了一个类,它包含对象的弱引用,并将调用转发给:
#import <Foundation/Foundation.h>
@interface WeakRefClass : NSObject
+ (id) getWeakReferenceOf: (id) source;
- (void)forwardInvocation:(NSInvocation *)anInvocation;
@property(nonatomic,assign) id source;
@end
@implementation WeakRefClass
@synthesize source;
- (id)init{
self = [super init];
// if (self) {
// }
return self;
}
+ (id) getWeakReferenceOf: (id) _source{
WeakRefClass* ref = [[WeakRefClass alloc]init];
ref.source = _source; //hold weak reference to original class
return [ref autorelease];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [[self.source class ] instanceMethodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
[anInvocation invokeWithTarget:self.source ];
}
@end
Run Code Online (Sandbox Code Playgroud)
你像这样使用它:
statusTimer = [NSTimer scheduledTimerWithTimeInterval: 1 target: [WeakRefClass getWeakReferenceOf:self] selector: @selector(updateStatus) userInfo: nil repeats: YES];
Run Code Online (Sandbox Code Playgroud)
你的dealloc方法被调用(与之前不同),你只需调用它:
[statusTimer invalidate];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7338 次 |
| 最近记录: |