繁体   English   中英

EXC_BAD_ACCESS objective-c块

[英]EXC_BAD_ACCESS objective-c block

我在viewDidLoad方法中运行此代码以从Firebase获取数据以将其放入UIPageViewController

@interface MapViewController () <RoutesPageDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (weak, nonatomic) RoutesPageViewController *routesPageViewController;
@property (weak, nonatomic) FIRFirestore *db;
@end

@implementation MapViewController

- (void) viewDidLoad {
    [super viewDidLoad];

    self.db = [FIRFirestore firestore];

    for (UIViewController *obj in self.childViewControllers) {
        if ([obj isKindOfClass:[RoutesPageViewController class]]) {
            self.routesPageViewController = (RoutesPageViewController *)obj;
            self.routesPageViewController.routesPageDelegate = self;
        }
    }

    FIRCollectionReference *routesRef = [self.db collectionWithPath:@"routes"];
    [routesRef getDocumentsWithCompletion:^(FIRQuerySnapshot * _Nullable snapshot, NSError * _Nullable error) {
        if (error != nil) {
            // TODO: handle error
        } else {
            NSMutableArray<RouteModel*> *routes = [NSMutableArray array];

            // For each route
            for (FIRDocumentSnapshot *document in snapshot.documents) {
                RouteModel *route = [[RouteModel alloc] init];
                route.title = document.data[@"title"];
                route.color = document.data[@"color"];
                route.city = document.data[@"city"];

                [routes addObject:route];
            }

            [self.routesPageViewController setRoutes:routes];
        }
    }];


}

这就是所谓的setRoutes方法:

- (void) setRoutes:(NSMutableArray<RouteModel *> *)routes {
    self.routes = routes;

    NSMutableArray<RoutePageViewController *> * routeViewControllers = [NSMutableArray array];
    for (RouteModel * route in routes) {
        [routeViewControllers addObject:[self viewControllerAtIndex:[routes indexOfObject:route]]];
    }

    [self setViewControllers:routeViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}

setRoutes方法被执行时,它会在下面的图像中抛出错误,说它无法取消引用它:

在此输入图像描述

setRoutes方法在块内执行。

我得到这个奇怪的线程堆栈: 在此输入图像描述

我怎么解决这个问题?

你的问题在这里:

- (void) setRoutes:(NSMutableArray<RouteModel *> *)routes {
    self.routes = routes;

调用self.routes implicity会调用setter setRoutes ,它会导致堆栈指示的递归无限调用。

在将块传递给getDocumentsWithCompletion方法执行时, routes数组已经被释放并设置为nil因为没有人将它保留在块外的任何地方。

您应该将其移动到块中或将其声明为类属性,以便在类实例处于活动状态时不会将其抛出内存。

[routesRef getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) {
    NSMutableArray<RouteModel*> *routes = [NSMutableArray array];
    ...
    [self.routesPageViewController setRoutes:routes];
}];

更新后:

执行self.routes = routes调用setRoutes:这反过来导致代码中的循环。 您应该将其更改为:

- (void)setRoutes:(NSMutableArray<RouteModel *> *)routes {
  if (_routes != routes) {
    _routes = routes;
    ...
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM