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
方法在块内执行。
我得到了这个奇怪的线程堆栈:
我该如何解决?
当块被传递到执行 getDocumentsWithCompletion
方法时,routes
数组已经被释放并设置为 nil
因为没有人在块外的任何地方保留它.
您应该将它移动到块中或将其声明为 class 属性,这样当 class 实例处于活动状态时它不会被抛出内存。
[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;
...
}
}
您的问题在这里:
- (void) setRoutes:(NSMutableArray<RouteModel *> *)routes {
self.routes = routes;
调用 self.routes
隐式调用了 setter setRoutes
,这会导致堆栈指示的递归无限调用。
我 运行 我的 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
方法在块内执行。
我得到了这个奇怪的线程堆栈:
我该如何解决?
当块被传递到执行 getDocumentsWithCompletion
方法时,routes
数组已经被释放并设置为 nil
因为没有人在块外的任何地方保留它.
您应该将它移动到块中或将其声明为 class 属性,这样当 class 实例处于活动状态时它不会被抛出内存。
[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;
...
}
}
您的问题在这里:
- (void) setRoutes:(NSMutableArray<RouteModel *> *)routes {
self.routes = routes;
调用 self.routes
隐式调用了 setter setRoutes
,这会导致堆栈指示的递归无限调用。