如何为全局 class 调用特定函数?

How to call specific function for a global class?

我的应用程序中有一些 Realm 模型都使用了一个基础 class。在此 class 中,我编写了一些通用函数,如下所示:

- (void)save {
    self.updatedAt = [NSDate date];
    [self.realm beginWriteTransaction];
    [self.realm addOrUpdateObject:self];
    [self.realm commitWriteTransaction];
    [[SyncEngine sharedInstance] store:self];
}

现在,我还写了一个叫做SyncEngine的class,它检查是否启用了一些可用的同步方法,然后调用它们:

- (void)store:(id)object {
    if ([Preferences CloudKitEnabled]) {
        [self.cloudKit store:object];
    }
}

这就是我的问题所在。我写了一个名为 CloudKitManager 的基础 class,它具有一些通用功能。然后我为我的应用程序中的每个模型创建一个特定的 CloudKitClass,所以我最终会得到 CloudKitRestaurantCloudKitTable。所有这些都将包含一个函数 (void)store:(id)sender。根据存储在 Realm 中的 class,调用特定 CloudKit class 的存储函数的最佳方法是什么?

理想情况下,我希望 RLMRestaurant 自动使用 CloudKitRestaurant 而不必使用 and if else 或 switch 语句。

为了进一步说明,这就是 SyncEngine 的工作原理。

@interface SyncEngine()

@property (nonatomic, strong) CloudKitManager *cloudKitManager;

@end

@implementation SyncEngine

static SyncEngine *sharedInstance = nil;

+ (SyncEngine *)sharedInstance {

    if (sharedInstance == nil) {
        sharedInstance = [[self alloc] init];
    }
    return sharedInstance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.cloudKitManager = [[CloudKitManager alloc] init];
    }
    return self;
}

@end

在我看来,您应该将 CloudKitManager class 的类型保留在 RLMBase 对象中。而当你需要调用[[CloudKitManager sharedInstance] store:object]时,调用[[object.cloudKitClass sharedInstance] store:object].

试试下面我的代码。

@interface RLMBase : NSObject

- (Class)cloudKitClass;

@end

@implementation RLMBase

- (Class)cloudKitClass {
  // Must be overridden in subclass.
  return CloudKitManager.class;
}

@end

@interface RLMRestaurant : RLMBase

@end

@implementation RLMRestaurant

- (Class)cloudKitClass {
  return CloudKitRestaurant.class;
}

@end

- (void)store:(RLMBase *)object {
  if ([Preferences CloudKitEnabled]) {
    [[object.cloudKitClass sharedInstance] store:object];
  }
}

另一种方式

store: 方法从 SyncEngine 放入 RLMBase 对象。

@interface RLMBase : NSObject

- (Class)cloudKitClass;
- (void)store;

@end

@implementation RLMBase

- (Class)cloudKitClass {
  // Must be overridden in subclass.
  return CloudKitManager.class;
}

- (void)store {
  if ([Preferences CloudKitEnabled]) {
    [[self.cloudKitClass sharedInstance] store:self];
  }
}

@end

save方法会变成

- (void)save {
  self.updatedAt = [NSDate date];
  [self.realm beginWriteTransaction];
  [self.realm addOrUpdateObject:self];
  [self.realm commitWriteTransaction];
  [self store];
}