4

您将如何实现以下实例方法NSSet

- (BOOL)containsMemberOfClass:(Class)aClass

这就是我想知道的原因:

核心数据模型:在此处输入图像描述

如何将 Facebook 授权添加到用户的授权NSSet中,但前提是该授权尚不存在。换句话说,一个用户可以有很多授权(如果我选择在将来添加一个 Twitter(例如)授权),但每种授权应该只有一个。所以,if (![myUser.authorizations containsMemberOfClass:[Facebook class]])然后添加一个 Facebook 授权实例到myUser.

4

5 回答 5

3

不幸的是,您必须遍历所有授权并检查:

@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
于 2011-04-29T21:52:42.637 回答
1

对于 Core Data,最好的做法是使用带有 NSPredicate 的 NSFetchRequest。为此,您必须向 Authorization 对象添加一个属性,例如 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 文档

于 2011-04-29T22:11:16.070 回答
0

如果将此实例方法添加到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;
}
于 2011-04-29T23:25:42.187 回答
0

你这样做是错误的。如果授权类型是常见且重要的,那么您应该直接在数据模型中对其进行建模,而不是尝试在外部控制器代码中强加该结构。

如果您有一组固定的授权,那么您应该创建一个实体来为这些授权建模。

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) 在不破坏数据模型的情况下轻松添加和删除接口元素。

于 2011-04-30T16:39:50.137 回答
0

老问题,但答案略有不同:

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
}
于 2013-11-12T11:26:53.473 回答