【问题标题】:The application is modifying the Autolayout Engine from background thread应用程序正在从后台线程修改自动布局引擎
【发布时间】:2017-02-13 09:57:28
【问题描述】:

据我所知,我不会从后台更新用户界面。

这是我的根视图控制器:

#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 作为根视图,并以导航控制器作为其根

【问题讨论】:

    标签: ios objective-c iphone uikit


    【解决方案1】:

    尝试调查 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];
    }
    

    这会导致它更新 UI:

    -(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 这将导致崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 2016-06-20
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多