Objective-C动态实施

时间:2016-06-03 20:12:20

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

说明+示例+解释(您可以跳到问题部分)

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

简单声明

@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)。相反,继承的类(在线/离线)用不同的实现覆盖父登录的方法(如在注释中)

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

@implement InternetManager

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

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

@end

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

  1. 这意味着我有2个继承的LoginController而不是1的实例。
  2. internetStatusoffline更改为online时,我想重新登录(获取session / oauthToken ...)。但是,我必须做很多事情(复制用户,更改实例,检查保留...)才可以实际通过在线登录来打电话
  3. 问题:

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

    更新问题:

    引用Apple的Dynamic typing

      

    isa指针:

         

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

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

1 个答案:

答案 0 :(得分:3)

听起来真正的问题是,你已经将这些东西直接归属于你实际上不希望他们拥有的国家的主要所有权 - 将其排除在外。没有复制,只需给每个在-init编组状态的事件的实例,并允许他们与之交谈。

然后,当你想根据条件做一件事或另一件事时,做正常的编程事情:使用if语句。

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

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

此常规区域的常见替代方法是不更改现有实例的类,而是更改作为类成员的方法。所以你有两个-loginByEmail:password:的替代实现,并设置哪个是实际响应该选择器的动态。但是,如果您可以访问源代码并且围绕其通常是间接的,不透明的性质,那么仅仅使用if就没有优势了。整件事通常被称为混合。 class_replaceMethod是关键组件,但只是搜索混合。