Как я могу проверить, содержит ли NSSet объект своего рода класса? - PullRequest
4 голосов
/ 30 апреля 2011

Как бы вы реализовали следующий метод экземпляра для NSSet:

- (BOOL)containsMemberOfClass:(Class)aClass

Вот почему я хочу знать:

Модель базовых данных: enter image description here

Как добавить авторизацию Facebook к авторизации пользователя NSSet, но только если она еще не существует. Другими словами, у пользователя может быть много авторизаций (в случае, если я решу добавить авторизацию Twitter (например, в будущем)), но у него должна быть только одна авторизация каждого типа. Итак, if (![myUser.authorizations containsMemberOfClass:[Facebook class]]), затем добавьте экземпляр авторизации Facebook в myUser.

Ответы [ 5 ]

3 голосов
/ 30 апреля 2011

К сожалению, вы должны пройти через все авторизации и проверить:

@interface NSSet (ContainsAdditions)

- (BOOL)containsKindOfClass:(Class)class;
- (BOOL)containsMemberOfClass:(Class)class;

@end

@implementation NSSet (ContainsAdditions)

- (BOOL)containsKindOfClass:(Class)class {
    for (id element in self) {
        if ([element isKindOfClass:class])
            return YES;
    }
    return NO;
}

- (BOOL)containsMemberOfClass:(Class)class {
    for (id element in self) {
        if ([element isMemberOfClass:class])
            return YES;
    }
    return NO;
}

@end
1 голос
/ 30 апреля 2011

Для базовых данных на самом деле рекомендуется использовать NSFetchRequest с NSPredicate.Для этого вам нужно добавить атрибут к вашему объекту авторизации, что-то вроде authorizationType.Затем вы можете сделать следующее:

NSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY user.authorizations.authorizationType == %@", @"facebook"];
[request setEntity:[NSEntityDescription entityForName:@"Authorization" inManagedObjectContext:moc]];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *result = [moc executeFetchRequest:request error:&error];

Затем вы можете проверить счетчик result, чтобы увидеть, существует он или нет.Использование NSPredicate позволяет использовать любые оптимизации, добавленные Apple в отношении CoreData.Вот Apple Docs .

0 голосов
/ 12 ноября 2013

Старый вопрос, но немного другой ответ:

NSPredicate *objectTypeFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject isKindOfClass:NSClassFromString(@"MyObject")];
}];
NSSet *myObjects =[allObjects filteredSetUsingPredicate:objectTypeFilter];
if (myObjects.count>0) {
    // There was at least one object of class MyObject in the allObjects set
}
0 голосов
/ 30 апреля 2011

Вы идете об этом неправильно.Если типы авторизации являются чем-то общим и важным, то вам следует смоделировать это непосредственно в модели данных, а не пытаться навязать эту структуру в коде внешнего контроллера.

Если у вас есть фиксированный набор полномочий, вам следует создать объект для моделирования этих полномочий.

Facebook{
    accessToken:string
    experationDate:date
    authorization<-->Authorizations.facebook
}

Google{
    username:string
    password:string
    authorization<-->Authorizations.google
}

Authorizations{
    user<-->User.authorizations
    facebook<-->Facebook.authorization
    google<-->Google.authorization
}

Теперь у вас есть все ваши полномочия, записанные в модели данных, к которой они принадлежат.Чтобы подтянуть вещи больше.Вы можете добавить пользовательский метод в класс User, чтобы контролировать добавление и удаление авторизаций.

Ключевой идеей здесь является то, что вся логика, управляющая данными, должна быть как можно более инкапсулирована в модель данных.Это позволяет (1) тестировать все операции с данными независимо от интерфейса и (2) легко добавлять и удалять элементы интерфейса, не нарушая модель данных.

0 голосов
/ 30 апреля 2011

Что если вы добавите этот метод экземпляра в класс User?

- (BOOL)hasFacebookAuthorization {
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user.id == %@", [self id]];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Facebook"
                                   inManagedObjectContext:managedObjectContext]];
    [fetchRequest setPredicate:predicate];

    NSError *error;
    NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (!result) {
        // TODO: Handle the error appropriately.
        NSLog(@"hasFacebookAuthorization error %@, %@", error, [error userInfo]);
    }

    return [result count] > 0;
}
...