简体   繁体   中英

How to populate a UIPickerView with results from a NSFetchRequest using Core Data

I have a UIPickerView that I am trying populate with the results from a NSFetchRequest pulling data from a managedObjectContext. When I initialize my UIPickerView with the following, KCModalPickerView *pickerView = [[KCModalPickerView alloc] initWithValues:_userNames]; Xcode doesn't throw and warnings or errors, but when I build and run the app I am getting the following error.

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Account copyWithZone:]: unrecognized selector sent to instance 0x7a60ec70' * First throw call stack:

Now before you say this error is due to me not implementing the copyWithZone method in my vc, I want to point out that nowhere in my class files am I using the keyword copy

The method that I was told that is causinging the crash belongs to the KCModalPicker class implementation file. And the method looks like the following,

// edit this method
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
 return [self.values objectAtIndex:row];
} 

What do I need to change / edit / add to prevent this app from crashing?

Update

_usernames is a NSArray ...the results look like the following,

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Account" inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.propertiesToFetch = [NSArray arrayWithObject:[[entity propertiesByName] objectForKey:@"username"]];
NSError *error = nil;
NSArray _usernames = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

KCModalPickerView expects an array of NSString , you give it an array of Account . The framework tries to copy your instance because it thinks it's an NSString , which conforms to the NSCopying protocol and implements copyWithZone: . Your object does not, and there will be a [Account copyWithZone:]: unrecognized selector sent to instance exception.

Simply create an array of NSStrings by using the appropriate attribute from your Core Data object.

There are probably smarter ways for this, but this would be the obvious solution:

NSMutableArray *names = [NSMutableArray arrayWithCapacity:[_usernames count]];
for (Account *account in _usernames) {
    NSString *accountName = account.name;
    if (!accountName) {
        accountName = @"<Unknown Account>";
    }
    [names addObject:accountName];
}
KCModalPickerView *pickerView = [[KCModalPickerView alloc] initWithValues:names];

I just saw that you have set propertiesToFetch . Additionally you have to set resultsType of the fetchRequest to NSDictionaryResultType . In this case executeFetchRequest:error: returns an array of dictionaries. And you should be able to use NSArray *names = [_usernames valueForKey:@"username"]; instead of the for loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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