应用程序正在从后台线程修改Autolayout引擎
问题描述:
据我所知,我不是从后台更新ui。应用程序正在从后台线程修改Autolayout引擎
这是我的根视图控制器:
#import "ContactsListViewController.h"
#import "ContactList.h"
#import "ModelLoadedDelegate.h"
#import "ContactDisplayingViewController.h"
#import "AddContactViewController.h"
@interface ContactsListViewController()
@property ContactList * currentModel;
@property NSIndexPath* indexToDisplay;
@property(strong,nonatomic) ContactList * originalModel;
@property (nonatomic) BOOL isModelSet;
@property UIBarButtonItem * addContactButton;
@property UISearchBar * theSearchTextField;
@property UIActivityIndicatorView * loadingIndicator;
@end
@implementation ContactsListViewController
@synthesize originalModel = _originalModel;
#pragma mark - The life cycle methods
-(void) awakeFromNib{
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
-(void)createView{
//self.automaticallyAdjustsScrollViewInsets = NO;
self.tableView = [[UITableView alloc]init];
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
//Refresh Control
self.refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl.backgroundColor = [UIColor purpleColor];
self.refreshControl.tintColor = [UIColor whiteColor];
[self.refreshControl addTarget:self
action:@selector(refreshDataFromTheFile)
forControlEvents:UIControlEventValueChanged];
self.refreshControl.translatesAutoresizingMaskIntoConstraints = NO;
//Background Label
UILabel * noContact = [[UILabel alloc]init];
noContact.text = @"No Contact to display";
noContact.textAlignment = NSTextAlignmentCenter;
self.tableView.backgroundView = noContact;
self.tableView.backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
//Loading indicator
self.loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
self.loadingIndicator.center = self.view.center;
self.loadingIndicator.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.loadingIndicator];
[self.loadingIndicator startAnimating];
//Constraints for the table
NSLayoutConstraint *myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
//Constraints for the loading indicator
/*
myConstraint = [NSLayoutConstraint constraintWithItem:self.loadingIndicator attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.loadingIndicator attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
[self.view addConstraint:myConstraint];
*/
/*
myConstraint = [NSLayoutConstraint constraintWithItem:self.loadingIndicator
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.tableView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.loadingIndicator
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.tableView
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
*/
//Constraints for the background view
/*
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView.backgroundView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView.backgroundView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView.backgroundView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
myConstraint = [NSLayoutConstraint constraintWithItem:self.tableView.backgroundView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0];
[self.view addConstraint:myConstraint];
*/
NSLog(@"The height of the navigation bar is %f",self.navigationController.navigationBar.frame.size.height);
//self.tableView.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height,0,0,0);
//Setting naviagation bar to translucent
self.navigationController.navigationBar.translucent = YES;
self.navigationController.view.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.backgroundColor = [UIColor colorWithRed:0/255.0f green:119/255.0f blue:255/255.0f alpha:0.3f];
self.tableView.backgroundColor = [UIColor colorWithRed:0/255.0f green:119/255.0f blue:255/255.0f alpha:0.3f];
//Adding the navigation bar items
NSLog(@"Is the navigation bar translucent? %d",[self.navigationController.navigationBar isTranslucent]);
UIBarButtonItem *barButton = [[UIBarButtonItem alloc]initWithTitle:@"Add Contact" style:UIBarButtonItemStylePlain target:self action:@selector(addContact:)];
[barButton setTitle:@"Add Contact"];
self.navigationItem.leftBarButtonItem = barButton;
self.addContactButton = self.navigationItem.leftBarButtonItem;
UISearchBar *searchBar=[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.navigationController.navigationBar.frame.size.width*.4, self.navigationController.navigationBar.frame.size.height/1.5)];
self.theSearchTextField = searchBar;
self.navigationItem.titleView = searchBar;
}
- (void)viewDidLoad {
NSLog(@"View did load called");
[super viewDidLoad];
[self createView];
self.theSearchTextField.delegate = self;
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
self.originalModel = [[ContactList alloc]init];
self.originalModel.delegate = self;
[self.originalModel retrieveOperation];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.editButtonItem.title = @"Delete Contacts";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) viewWillAppear:(BOOL)animated{
NSLog(@"The origin of the table view is at %f",self.tableView.frame.origin.y);
//[self updateUI];
}
#pragma mark - Event Handlers
-(IBAction) addContact:(UIButton *)sender{
AddContactViewController * add = [[AddContactViewController alloc]init];
add.delegate = self;
[self.navigationController presentViewController:[[UINavigationController alloc]initWithRootViewController: add] animated:true completion:^{
}];
}
- (IBAction)changeTheModelForSearching:(UITextField *)sender {
NSLog(@"The searching method is called");
if(sender.text.length == 0){
[self.originalModel setContactListFromList:[[self.currentModel ContactList] mutableCopy]];
self.currentModel = nil;
}
else{
if(!self.currentModel){
self.currentModel = [[ContactList alloc]init];
[self.currentModel setContactListFromList: [[self.originalModel ContactList]mutableCopy]];
}
[self.originalModel setContactListFromList: [[self.originalModel searchContact:sender.text] mutableCopy]];
}
[self updateUI];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Number of section is called");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"Number of rows is called");
if(self.isModelSet){
NSLog(@"The if is okeyy");
return [self.originalModel getNoOfContacts];
}
NSLog(@"The if isnt okeyy");
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Cellforrow called");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Individual Contact"];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: @"Individual Contact"];
if(self.theSearchTextField.text.length == 0){
NSLog(@"Search Text length is zero");
if(self.originalModel && self.isModelSet){
Contact * currentContact = [self.originalModel ContactList][indexPath.row];
cell.textLabel.text = [currentContact name];
cell.detailTextLabel.text = [currentContact number];
}
}
else{
if(self.originalModel && self.isModelSet){
Contact * currentContact = [self.originalModel ContactList][indexPath.row];
NSRange rangeOfOccurence = [[currentContact name] rangeOfString:self.theSearchTextField.text];
NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc]initWithString:currentContact.name];
if(rangeOfOccurence.location != NSNotFound)
[attrString addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithRed:((float)230/255.0) green:((float)255/255.0) blue:((float)255/255.0) alpha:1.0] range:rangeOfOccurence];
cell.textLabel.attributedText = attrString;
if([[currentContact email] containsString:self.theSearchTextField.text] && ![[currentContact number] containsString:self.theSearchTextField.text]){
rangeOfOccurence = [[currentContact email]rangeOfString:self.theSearchTextField.text];
attrString = [[NSMutableAttributedString alloc]initWithString:currentContact.email];
[attrString addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithRed:((float)230/255.0) green:((float)255/255.0) blue:((float)255/255.0) alpha:1.0] range:rangeOfOccurence];
cell.detailTextLabel.attributedText = attrString;
}
else{
rangeOfOccurence = [[currentContact number]rangeOfString:self.theSearchTextField.text];
attrString = [[NSMutableAttributedString alloc]initWithString:currentContact.number];
[attrString addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithRed:((float)230/255.0) green:((float)255/255.0) blue:((float)255/255.0) alpha:1.0] range:rangeOfOccurence];
cell.detailTextLabel.attributedText = attrString;
}
}
}
return cell;
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if(editing){
self.editButtonItem.title = @"Done";
}
else{
self.editButtonItem.title = @"Delete";
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.originalModel deleteContactAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
#pragma mark - Delegate Methods
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if(!self.currentModel){
self.currentModel = [[ContactList alloc]init];
[self.currentModel setContactListFromList: [[self.originalModel ContactList]mutableCopy]];
}
if(searchBar.text.length == 0){
[self.originalModel setContactListFromList:[[self.currentModel ContactList] mutableCopy]];
self.currentModel = nil;
}
else{
[self.originalModel setContactListFromList: [[self.originalModel searchContact:searchBar.text] mutableCopy]];
}
[self updateUI];
}
-(void)refreshDataFromTheFile{
ContactList * list = [[ContactList alloc]init];
list.delegate = self;
[list retrieveOperation];
}
#pragma mark - Protocol Methods
-(void) modelIsSet{
[self.loadingIndicator stopAnimating];
NSLog(@"The model is set");
self.isModelSet = true;
[self updateUI];
[self.refreshControl endRefreshing];
NSLog(@"the number of contacts is %lul",(unsigned long)[[self originalModel]getNoOfContacts]);
}
-(void) updateUI{
[self.tableView reloadData];
}
#pragma mark - Helper Methods
-(void)setOriginalModel:(ContactList *)originalModel{
NSLog(@"Set model is called");
if(!self.originalModel)
_originalModel = originalModel;
}
@end
联系人列表类:
#import <Foundation/Foundation.h>
#import "ContactList.h"
#import "Contact.h"
#import "FileRetrieving.h"
#import "NSStringCategory.h"
#import "ModelLoadedDelegate.h"
#import "ContactsListViewController.h"
@interface ContactList()
@property(nonatomic , strong) NSMutableArray * contactList;
@property(nonatomic,strong) NSOperationQueue *queue;
@property(nonatomic) BOOL handling;
@end
@implementation ContactList
@synthesize contactList;
-(NSUInteger) getNoOfContacts{
return [[self contactList] count];
}
-(void)setContactListFromList:(NSMutableArray *)list{
self.contactList = [list mutableCopy];
}
/*-(void) main{
self.contactList = [NSMutableArray array];
NSData *data = [NSData dataWithContentsOfFile:@"theListFile"];
NSArray * tempArr = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
for (NSArray * individualContacts in tempArr){
Contact * cont = [[Contact alloc]init];
[cont setNumber:individualContacts[1]];
[cont setEmail:individualContacts[0]];
[cont setName:individualContacts[2]];
[self.contactList addObject:cont];
}
}*/
-(void)saveToArray:(NSMutableArray *)arr{
NSLog(@"Save to array called");
self.contactList = [arr mutableCopy];
self.delegate = ((ContactsListViewController *)self.delegate);
[self.delegate setOriginalModel:self];
[self.delegate modelIsSet];
}
-(NSArray *) ContactList{
return self.contactList;
}
-(void) deleteContactAtIndex: (NSUInteger) index{
[self.contactList removeObjectAtIndex:index];
[self save];
}
-(void)sortTheList{
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES];
NSSortDescriptor *numberDescriptor = [[NSSortDescriptor alloc]initWithKey:@"number" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObjects:nameDescriptor,numberDescriptor, nil];
[self.contactList sortUsingDescriptors:descriptors];
}
-(NSMutableArray *) differenceBetweenTheContactLists :(NSMutableArray *)array{
NSMutableArray * temp = [NSMutableArray array];
temp = [contactList mutableCopy];
[temp removeObjectsInArray:array];
return temp;
}
-(BOOL) doesDuplicateExist:(Contact *)contact{
NSPredicate *namePred = [NSPredicate predicateWithFormat:@"SELF.name LIKE %@ AND SELF.secondName LIKE %@ AND SELF.email like %@ AND SELF.number == %d",contact.name,contact.email,contact.number];
if([[self.contactList filteredArrayUsingPredicate:namePred] count] == 0)
return NO;
else return YES;
}
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context
{
if (self.handling){
self.handling = NO;
}
}
-(id) init{
self = [super init];
self.contactList = [NSMutableArray array];
/*NSOperation *op = [[NSOperation alloc]init];
[op setCompletionBlock:^{
self.contactList = [NSMutableArray array];
NSData *data = [NSData dataWithContentsOfFile:@"theListFile"];
NSArray * tempArr = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
for (NSArray * individualContacts in tempArr){
Contact * cont = [[Contact alloc]init];
[cont setNumber:individualContacts[1]];
[cont setEmail:individualContacts[0]];
[cont setName:individualContacts[2]];
[self.contactList addObject:cont];
}
}];
[self.queue addOperation:op];*/
/*[self.queue addOperationWithBlock:^{
self.contactList = [NSMutableArray array];
NSData *data = [NSData dataWithContentsOfFile:@"theListFile"];
NSArray * tempArr = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
for (NSArray * individualContacts in tempArr){
Contact * cont = [[Contact alloc]init];
[cont setNumber:individualContacts[1]];
[cont setEmail:individualContacts[0]];
[cont setName:individualContacts[2]];
[self.contactList addObject:cont];
}
}];*/
if(!contactList)
contactList = [NSMutableArray array];
return self;
}
-(void)retrieveOperation{
FileRetrieving * retrieve = [[FileRetrieving alloc]init];
NSLog(@"%@",self);
self.selfRef = self;
retrieve.delegate = self;
retrieve.option = 1;
self.queue = [NSOperationQueue new];
[self.queue addOperation:retrieve];
}
-(void) save{
NSLog(@"Save is called");
FileRetrieving *ret = [[FileRetrieving alloc]init];
[ret setArray:self.contactList];
[ret setOption:2];
[[NSOperationQueue new]addOperation:ret];
}
/*
-(NSMutableArray *) differenceBetweenTheContactLists :(NSMutableArray *)array{
NSMutableArray * temp = [NSMutableArray array];
for (Contact * i in array){
if(![self doesDuplicateExist:i]){
[temp addObject:i];
}
}
return temp;
}*/
-(NSUInteger)addContact:(Contact *)cont{
BOOL isAdded = false;
if ([cont.email checkEmailId] || [cont.email isEqualToString:@" "]){
if(![self doesDuplicateExist:cont]){
[self.contactList addObject:cont];
isAdded = true;
}
else{
NSLog(@"Duplication!");
}
}
else{
NSLog(@"Not an email id");
}
if (isAdded){
[self sortTheList];
[self save];
}
return [self.contactList indexOfObject:cont];
}
-(NSUInteger) addContact:(NSString *)name secondName: (NSString *) secondName forNumber:(NSString *)number andEmail:(NSString *)email andDate:(NSDate *)date andExpiryDate:(NSDate *)expiry{
NSLog(@"Add contacts is called");
BOOL isAdded = false;
Contact *temp = [[Contact alloc]init];
if ([email checkEmailId] || [email isEqualToString: @" "]){
[temp setName:name];
[temp setSecondName:secondName];
[temp setEmail: email];
[temp setNumber:number];
[temp setDate:date];
[temp setExpiryDate:expiry];
if(![self doesDuplicateExist:temp]){
[self.contactList addObject:temp];
isAdded = true;
}
else{
NSLog(@"Duplication!");
}
}
else{
NSLog(@"Not an email id");
}
if (isAdded){
[self sortTheList];
[self save];
}
return [self.contactList indexOfObject:temp];
}
-(NSIndexSet *) deleteContact:(Contact *)cont{
NSPredicate *namePred = [NSPredicate predicateWithFormat:@"NOT SELF.name LIKE %@ AND NOT SELF.secondName LIKE %@ AND NOT SELF.email LIKE %@ AND NOT SELF.number == %d",cont.name,cont.secondName,cont.email,cont.number];
/*NSMutableArray *tempArr = [NSMutableArray array];
for(Contact * temp in [self contactList]){
if(![pred evaluateWithObject:temp]){
[tempArr addObject:temp];
}
}
[self setContactList:tempArr];*/
NSIndexSet * indexes = [self.contactList indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj = ((Contact *)obj);
return [[obj name] isEqualToString:[cont name]] || [[obj email] isEqualToString:[cont email]] || [[obj number] isEqualToString:[cont number]] || [[obj secondName] isEqualToString:[cont secondName]];
}];
[self.contactList filterUsingPredicate:namePred];
if([indexes count] > 0)
[self save];
return indexes;
}
/*
-(void) deleteContact:(NSString *)name{
NSPredicate *deletePred = [NSPredicate predicateWithFormat:@"NOT SELF.name LIKE[c] %@",name];
int count = [[self contactList] count];
[self setContactList:[NSMutableArray arrayWithArray:[[self contactList] filteredArrayUsingPredicate:deletePred]]];
NSLog(@"%d contacts affected",count-[[self contactList] count]);
}*/
-(BOOL) doesContactExist:(NSString *)name{
NSPredicate *tempPred = [NSPredicate predicateWithFormat:@"SELF.name LIKE[c] %@", name];
NSPredicate *secondNamePred = [NSPredicate predicateWithFormat:@"SELF.secondName LIKE %@",name];
NSPredicate *emailPred = [NSPredicate predicateWithFormat:@"SELF.email CONTAINS %@", name];
NSMutableArray *preds = [NSMutableArray new];
[preds addObject:tempPred];
[preds addObject:emailPred];
[preds addObject:secondNamePred];
//NSPredicate *tempPred = [NSPredicate predicateWithFormat:@"SELF matches %@",name];
/*if(([[[self contactList]filteredArrayUsingPredicate:tempPred]count] + [[[self contactList]filteredArrayUsingPredicate:emailPred]count]) > 0)
[self contactList]filt
return YES;
return NO;*/
NSCompoundPredicate *compPred = [NSCompoundPredicate orPredicateWithSubpredicates:preds];
if([[[self contactList] filteredArrayUsingPredicate:compPred]count] > 0)
return YES;
return NO;
}
-(NSArray *) searchContact:(NSString *)name{
NSPredicate *namePred = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS %@ OR SELF.secondName CONTAINS %@ OR SELF.email CONTAINS %@ OR SELF.number CONTAINS %@",name,name,name,name];
return [self.contactList filteredArrayUsingPredicate:namePred];
}
@end
文件检索和JSON处理程序是否工作正常。在应用程序委托我已经添加的contactslistviewcontroller作为与导航控制器作为其根
答
尝试调查saveToArray方法根视图,要发送消息给ContactsListViewController:
-(void)saveToArray:(NSMutableArray *)arr{
NSLog(@"Save to array called");
self.contactList = [arr mutableCopy];
self.delegate = ((ContactsListViewController *)self.delegate);
[self.delegate setOriginalModel:self];
[self.delegate modelIsSet];
}
那导致它更新用户界面:
-(void) modelIsSet{
[self.loadingIndicator stopAnimating];
NSLog(@"The model is set");
self.isModelSet = true;
[self updateUI];
[self.refreshControl endRefreshing];
NSLog(@"the number of contacts is %lul",(unsigned long)[[self originalModel]getNoOfContacts]);
}
但是,您不确定这是分派在主线程上我这两个地方都没有。我不能肯定地说这是你的问题的原因,但是如果你在主线程以外的任何地方使用saveToArray,这会导致崩溃。