如何检查 NSSet 是否包含某种类的对象?

发布于 2024-11-04 08:06:50 字数 455 浏览 0 评论 0原文

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

- (BOOL)containsMemberOfClass:(Class)aClass

这就是我想知道的原因:

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

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

How would you implement the following instance method for NSSet:

- (BOOL)containsMemberOfClass:(Class)aClass

Here's why I want to know:

Core Data model: enter image description here

How do I add a Facebook authorization to a user's authorizations NSSet, but only if one doesn't already exist. In other words, a user can have many authorizations (in case I choose to add a Twitter (e.g.) authorization in the future) but should only have one of each kind of authorization. So, if (![myUser.authorizations containsMemberOfClass:[Facebook class]]), then add a Facebook authorization instance to myUser.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

回忆躺在深渊里 2024-11-11 08:06:50

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

@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

Unfortunately, you have to loop through all of the authorizations and check:

@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
空城旧梦 2024-11-11 08:06:50

对于 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 文档

With Core Data it is actually best practice to use an NSFetchRequest with an NSPredicate. To do that you would have to add an attribute to your Authorization object, something like authorizationType. You could then do the following:

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];

You can then check the count of result to see if it exists or not. Using NSPredicate allows you to use any optimizations Apple has added around CoreData. Here are the Apple Docs.

野侃 2024-11-11 08:06:50

如果将此实例方法添加到 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;
}

What if you add this instance method to the User class?

- (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;
}
一袭白衣梦中忆 2024-11-11 08:06:50

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

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

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) 轻松添加和删除界面元素,而不会破坏数据模型。

Your going about this the wrong way. If the types of authorization are something common and important then you should model that in your data model directly instead of trying to impose that structure in external controller code.

If you have a fixed set of authorizations then you should create an entity to model those authorizations.

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
}

Now you have all your authorizations captured in the data model where they belong. To tighten things up more. You could add a custom method to the User class to control adding and removing authorizations.

The key idea here is that all the logic that manages data should be encapsulated in the data model to the greatest extent possible. This allows you to (1) test all data operations independent of the interface and (2) easily add and remove interface elements without breaking the data model.

不顾 2024-11-11 08:06:50

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

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
}

Old question, but slightly different answer:

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文