gpt4 book ai didi

ios - 注解 dealloc 方法从不在 ARC 中调用,底层的 viewcontroller dealloc 被调用

转载 作者:行者123 更新时间:2023-11-29 03:34:54 30 4
gpt4 key购买 nike

当我的应用程序开始在我的自定义注释方法中崩溃时,我了解到我的内存有问题。我确信管理 map 的 viewcontroller 100% 应该已经从 View 堆栈中弹出。

这里是注释的代码,TaxiArrivingAnnotation.h :

#import <Foundation/Foundation.h>
@import MapKit;

@interface TaxiArrivingAnnotation : NSObject<MKAnnotation>
@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (nonatomic) int minutesToTaxiArrival;

-(void) startTimer;
@end

TaxiArrivingAnnotation.m :

#import "TaxiArrivingAnnotation.h"

#define SECONDS_IN_A_MINUTE 60

@interface TaxiArrivingAnnotation ()
@property (nonatomic) NSTimer * timer;
@property (nonatomic) NSDate * timeOfArrival;
@property (nonatomic, weak) id token1;
@property (nonatomic, weak) id token2;
@end

@implementation TaxiArrivingAnnotation

- (id)init
{
self = [super init];
if (self) {
__weak TaxiArrivingAnnotation * this = self;

self.token1 = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note)
{
NSLog(@"DID BECOME ACTIVE");
NSTimeInterval secondsLeft = [this.timeOfArrival timeIntervalSinceNow];
if (secondsLeft < 0) {
self.minutesToTaxiArrival = 0;
return;
}

this.minutesToTaxiArrival = secondsLeft / SECONDS_IN_A_MINUTE;

[this startTimer];
}];

self.token2 = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note)
{
NSLog(@"WILL RESIGN ACTIVE");
[this.timer invalidate];
this.timer = nil;
}];

}
return self;
}


-(void) setMinutesToTaxiArrival:(int)newMinutes {
self->_minutesToTaxiArrival = newMinutes;
self->_timeOfArrival = [NSDate dateWithTimeIntervalSinceNow:SECONDS_IN_A_MINUTE * newMinutes];
if (newMinutes < 0) {
[self.timer invalidate];
}
}

-(void) startTimer {
self.timer = [NSTimer timerWithTimeInterval:SECONDS_IN_A_MINUTE target:self selector:@selector(aMinutedPassed) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
}

-(void) aMinutedPassed {
self.minutesToTaxiArrival--;
}

-(void) dealloc {
NSLog(@"DEALLOC");
if (self.timer != nil && [self.timer isValid])
[self.timer invalidate];
[[NSNotificationCenter defaultCenter] removeObserver:self.token1];
[[NSNotificationCenter defaultCenter] removeObserver:self.token2];
}
@end

我在 viewDidAppear 上添加注释,在 viewDidDisappear 上删除它。不仅删除它而且 nil 引用。管理viewcontrollerdealloc调用时,dealloc方法仍然没有被调用。

真正的问题是计时器和通知会触发,应用会崩溃,因为注解已被释放。

最佳答案

您正在尝试使 dealloc 中的重复计时器无效。问题是计时器保持对 target (您的注释)的强引用,这将阻止 dealloc 被调用(因为只有在没有更多的情况下才会调用它)强引用)。它类似于强引用循环(也称为保留循环)。

当 View Controller 被释放时(或者任何启动 View Controller 解散的逻辑事件),您必须使计时器无效。由于计时器将在到达 dealloc 时失效,因此您可以从注释的 dealloc 方法中删除 invalidate 代码,显然。

关于ios - 注解 dealloc 方法从不在 ARC 中调用,底层的 viewcontroller dealloc 被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19318436/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com