【问题标题】:Objective-C dynamic implementationObjective-C 动态实现
【发布时间】:2016-06-03 20:12:20
【问题描述】:

描述+示例+说明:(可以跳到问题部分)

我想做一个对象实例,它可以通过不同的实现来实现,取决于一个条件(互联网状态)。

简单声明

@interface LoginController : NSObject

/** The currently logged-in User. Nil if not logged-in yet. */
@property (strong, nonatomic) User *currentUser;

// Singleton object
+ (instancetype)shareInstance;

/** Abstract methods, will do nothing if call directly. Use inheritance implements (Online/Offline) instead. */
- (User *)loginByEmail:(NSString *)email password:(NSString *)pwd;

@end

@interface LoginControllerOnline : LoginController
// Login will call request to server.
@end

@interface LoginControllerOffline : LoginController
// Login will check data in coredata.
@end

LoginController 的登录方法实际上什么都不做(return nil)。相反,继承的类(在线/离线)覆盖了父登录的方法,具有不同的实现(如在 cmets 中)

然后,我有一个经理来定义应该使用哪个类:

@implement InternetManager

+ (LoginController *)loginController
{
    return [self hasInternet] ? [LoginControllerOnline shareInstance] : [LoginControllerOffline shareInstance];
}

+ (BOOL)hasInternet
{
    // Check with Reachability.
}

@end

这项工作。但这不是我想要实现的机制。

  1. 这意味着我有 2 个继承的 LoginController 实例而不是 1 个。
  2. internetStatusoffline 更改为online 时,我想重新在线登录(以获取会话/oauthToken...)。但是,我必须做很多事情(复制用户、更改实例、检查保留...)才能真正从在线登录调用

问题:

有没有办法让我只创建一个 LoginController 实例,它具有相同的属性 (User),但可以有不同的(动态)实现(在线/离线)?

更新问题:

引用苹果Dynamic typing

ISA 指针:

每个对象都有一个 isa 实例变量 标识对象的类。运行时使用这个指针来 在需要时确定对象的实际类。

那么,有没有办法让我改变这个对象实例的isa pointer

【问题讨论】:

    标签: ios objective-c inheritance design-patterns polymorphism


    【解决方案1】:

    听起来真正的问题在于,您已将您实际上不希望它们拥有的状态的直接主要所有权授予这些东西 - 将其排除在外。没有复制,只需给每个元帅在-init 指定的东西的实例,并允许他们与之交谈。

    然后,当您想根据条件执行一件事或另一件事时,只需执行正常的编程操作:使用 if 语句。

    所以,我认为使用动态运行时不合适。但是,在学术上,假设有兴趣:

    如果你真的必须,请使用object_setClass,它“[s]ets 对象的类”,回答你的实际问题。显然,您需要存储兼容,因此您的子类可能不应该声明任何属性或实例变量。

    对于这个一般领域,一个普遍讨论的替代方法不是更改现有实例的类,而是更改作为该类成员的方法。因此,您将有两个替代实现 -loginByEmail:password: 和 set 哪个是实际动态响应该选择器的实现。但是,如果您可以访问源代码以及围绕其通常是间接的、不透明的性质的一系列缺点,那么仅使用 if 确实没有任何优势。整个过程通常被称为 swizzling。 class_replaceMethod 是关键组件,但只需搜索 swizzling。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多