gpt4 book ai didi

ios - 有没有办法以通用方式替换关系的添加和删除方法的核心数据实现?

转载 作者:可可西里 更新时间:2023-11-01 06:15:53 25 4
gpt4 key购买 nike

请注意:这与 this question 不是同一个问题,因为我已经知道这源于 Apple 错误。请注意,覆盖特定方法(例如,-addFriendsObject:,如果我有 friend 关系)不是一种选择,因为我需要在类别中执行此操作,以便它适用于任何托管对象,而不管修改模型和重建从中自动生成类。

对此的需求源于这样一个事实,即显然在使关系有序化的那一刻,对多(NSMutableOrderedSets)核心数据动态方法就会陷入困境:

  1. 方法 -add<Relationship>Object , -add<Relationship> , -remove<Relationship>Object-remove<Relationship>都会崩溃,异常相似 'NSInvalidArgumentException', reason: '*** -[NSSet intersectsSet:]: set argument is not an NSSet'
  2. 按照 insertObject:in<Relationship>AtIndex: 的方法反而会崩溃,因为 CoreData 实际上没有为它们提供任何实现。

至于2,我写了一个覆盖-methodSignatureForSelector:的类别和 -forwardInvocation而是做类似 mutableOrderedSetValueForKey 的事情对于关系名称,后跟实际的添加或删除。

现在对于 1,问题是 CoreData 实际上为这些方法提供了实现(尽管它们不是有序集的正确实现)。所以我也需要一种拦截这些选择器的方法,这样我就可以通过 mutableOrderedSetValueForKey 实现行为。

有什么想法可以实现吗?

最佳答案

我不知道这是最好的方法(它肯定不是有史以来最漂亮的方法),但它完成了工作:

#import "NSManagedObject+OrderedSets.h"
#import <objc/runtime.h>

@implementation NSManagedObject (OrderedSets)

+ (void)swizzleMethod:(SEL)originalSelector with:(SEL)replacementSelector
{
const char *methodTypeEncoding = method_getTypeEncoding(class_getInstanceMethod([self class], originalSelector));
class_replaceMethod(self,
originalSelector,
class_getMethodImplementation(self, replacementSelector),
methodTypeEncoding);
}

+ (void)initialize
{
NSEntityDescription *selfEntity = // get a hold of your NSManagedObjectContext and from its entities grab model.entitiesByName[NSStringFromClass(self)] ...
for (NSString *rKey in [selfEntity relationshipsByName]) {
NSRelationshipDescription *r = selfEntity.relationshipsByName[rKey];
if (r.isOrdered) {
NSString *rKeyFirstCaps = [[rKey substringToIndex:1] capitalizedString];
NSString *capitalizedKey = [rKey stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:rKeyFirstCaps];
NSString *addSelectorString = [NSString stringWithFormat:@"add%@Object:", capitalizedKey];
NSString *removeSelectorString = [NSString stringWithFormat:@"remove%@Object:", capitalizedKey];
[self swizzleMethod:NSSelectorFromString(addSelectorString) with:@selector(addOrRemoveObjectInOrderedSet:)];
[self swizzleMethod:NSSelectorFromString(removeSelectorString) with:@selector(addOrRemoveObjectInOrderedSet:)];
}
}
}

- (void)addOrRemoveObjectInOrderedSet:(NSManagedObject*)object
{
NSString *selectorString = NSStringFromSelector(_cmd);
NSString *prefix = [selectorString hasPrefix:@"add"] ? @"add" : @"remove";
selectorString = [selectorString stringByReplacingCharactersInRange:[selectorString rangeOfString:prefix] withString:@""];
selectorString = [selectorString stringByReplacingCharactersInRange:[selectorString rangeOfString:@"Object" options:NSBackwardsSearch] withString:@""];
selectorString = [selectorString substringToIndex:selectorString.length - 1];
NSString *selectorFirstLowerCase = [[selectorString substringToIndex:1] lowercaseString];
NSString *camelCasedKey = [selectorString stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:selectorFirstLowerCase];

if ([prefix isEqualToString:@"add"]) {
[[self mutableOrderedSetValueForKey:camelCasedKey] addObject:object];
}
else {
[[self mutableOrderedSetValueForKey:camelCasedKey] removeObject:object];
}
}

@end

关于ios - 有没有办法以通用方式替换关系的添加和删除方法的核心数据实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16805624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com