ios - Objective-C 动态实现

标签 ios objective-c inheritance design-patterns polymorphism

说明+ sample +说明: (您可以跳到问题部分)

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

简单声明

@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

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

    问题:

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

    更新问题:

    引自 Apple 的 Dynamic typing :

    The isa Pointer:

    Every object has an isa instance variable that identifies the object's class. The runtime uses this pointer to determine the actual class of the object when it needs to.



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

    最佳答案

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

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

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

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

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

    关于ios - Objective-C 动态实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37622630/

    相关文章:

    ios - 在 UILabel 上写入 RTL 字符串

    javascript - UIWebView 中 PUT 或 POST 类型的 ajax 不传递 HTTP 主体

    ios - 为 iOS 创建从右到左的用户界面

    python - 使用不同的参数在 python 中调用父类(super class)构造函数

    ios - 在播放/暂停 UIButton 之间切换

    ios - 以编程方式定位按钮,结果出乎意料

    c# - 泛型类的方法看不到子类的 'new' 属性

    javascript - 使用 Douglas Crockford 的函数继承在 Javascript 中调用基方法

    ios - 在从 UIPickerView 选择的 NSTimer 的 UILabel 中显示秒数

    iphone - 识别圆圈手势以删除注释,如何检测圆圈?