【问题标题】:How to initialize an object and override a method in objective c?如何初始化对象并覆盖目标c中的方法?
【发布时间】:2013-01-23 14:03:47
【问题描述】:

像其他语言一样,我们可以在initialization 期间创建一个对象并覆盖对象中的一个方法。请帮帮我,我该怎么办?

例如:

    public class DemoInitAndOverride {

    public void handleMessage(){}

}

在另一个班级

    public class SampleClass {

    public void doSomeThing(){
        DemoInitAndOverride demo = new DemoInitAndOverride(){
            @Override
            public void handleMessage() {
                // TODO Auto-generated method stub
                super.handleMessage();
            }
        };
    }

}
****EDIT:****

感谢大家提供可能的解决方案和建议。我认为现在对我来说重要的是提供一些有关需求的详细信息,这可以帮助您提供解决方案。

处理程序的概念类似于 Android 框架,其中处理程序用于在 2 个线程或 2 个方法之间传递消息。请看下面的代码演示:

UI 类(此处用户单击按钮,使用处理程序将请求分派到处理器类)

这是演示处理程序

/**
 * 
 * Used for thread to thread communication.
 * Used for non UI to UI Thread communication.
 *
 */
public class DemoHandler {

    public void handleMessage(Messages message){}

    final public void sendMessage(final Messages message){
        //Calling thread is platform dependent and shall change based on the platform
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    handleMessage(message);
                }
            }
        });
    }
}

这是简单的消息类

public class Messages {
    public Object myObject;

    //other hash map (key, values) and get data put data etc
}

这是简单的用户界面类演示代码:

public class UIClass {

    public UIClass(){
        //INIT
    }
    void onClick(int id){
        //Some Button is clicked:
        //if id == sendParcel
        //do
        TransactionProcessor.getInstance().sendParcel(handler, "Objects");
    }

    DemoHandler handler = new DemoHandler(){
        public void handleMessage(Messages message) {
            //Inform the UI and Perform UI changes
            //data is present in the messages
        };
    };
}

这是示例事务处理器类

公共类 TransactionProcessor {

public static TransactionProcessor getInstance(){
    return new TransactionProcessor(); //for demonstration
}
//Various Transaction Methods which requires calling server using HTTP and process there responses:
public void sendParcel(final DemoHandler uiHander, String otherdetailsForParcel){
    //INIT Code and logical code
    //Logical Variables and URL generation
    String computedURL = "abc.com/?blah";
    DemoHandler serverConnectionHandler = new DemoHandler(){
        @Override
        public void handleMessage(Messages message) {
            super.handleMessage(message);
            //Process server response:
            //create a new message for the UI thread and dispatch
            Messages response = new Messages();
            //add details to messages
            //dispatch
            uiHander.sendMessage(response );
        }
    };
    new Thread(new ServerConnection(computedURL, serverConnectionHandler));
}
public void sendEmail(final DemoHandler uiHander, String otherdetailsForEmail){
    //SAME AS SEND PARCEL WITH DIFFERENT URL CREATION AND RESPONSE VALIDATIONS
}
public void sendNotification(final DemoHandler uiHander, String otherdetailsForNotifications){
    //SAME AS SEND PARCEL WITH DIFFERENT URL CREATION AND RESPONSE VALIDATIONS
}

}

【问题讨论】:

  • 删除[Java]作为答案与Java没有任何关系。
  • 谢谢,这是真的;答案与java无关
  • 在Objective-C中,只要你子类化它就会被自动覆盖,如果你想调用超类的方法,你需要调用[super method];
  • 你不能在没有创建子类的情况下覆盖 Objective-C 中的特定方法。不过看看代表,我想他们会给你想要的。
  • 取决于你想用它做什么。 Objective-C 有它自己的方式。您可能需要一个类别或扩展名,但这取决于您想用它做什么。在 Objective-C 中,我只知道用于单元测试的存根。这就是你想要的吗?

标签: objective-c overriding


【解决方案1】:

这是一个讨厌的,我建议创建一个子类或其他东西。

这是您的答案,基本相同,但在运行时。风险自负:

导入这个:

#import <objc/runtime.h>

并将这段代码添加到任何地方:

- (void)methodName {
    // whatever you want to do in there
}

在你的函数中:

Class subclass;
// Verifiy that you haven't created it already
subclass = objc_getClass("SampleClassSubclass");
if (!subclass) {
    // Generate a new class, which will be subclass of your SampleClass
    subclass = objc_allocateClassPair(subclass, "SampleClassSubclass", 0);
    // Obtain the implementation of the method you want to overwrite
    IMP methodImplementation = [self methodForSelector:@selector(methodName)];
    // With that implementation, replace the method
    class_replaceMethod(subclass, @selector(methodName), methodImplementation, "@@:");
    // Register the class you just generated
    objc_registerClassPair(subclass);
}

SampleClass *obj = [[subclass alloc] init];

【讨论】:

  • 谢谢@Ismael。我对演示代码进行了更改。如果您可以通过它并建议我一些等效的实现或方法,那就太好了。整个类的实例更改将使我的实现失败。
【解决方案2】:

在 Objective-C 中并不容易做到,但这应该可以。它用自己的实现替换DemoInitAndOverridedoSomething 方法并返回该类的新实例。但是请注意,一旦完成此操作,新的实现仍然适用于类的所有新实例,而不仅仅是单个实例。

- (void)doSomething
{
    NSLog(@"self doSomething called");
}

- (DemoInitAndOverride *)createObj
{
    DemoInitAndOverride *obj = [[DemoInitAndOverride alloc] init];

    SEL sel = @selector(doSomething);
    Method theirMethod = class_getInstanceMethod([DemoInitAndOverride class], sel);
    Method myMethod = class_getInstanceMethod([self class], sel);
    theirMethod->method_imp = myMethod->method_imp;
    return obj;
}

【讨论】:

  • 感谢@trojanfoe,由于我使用对象和方法的多次启动以及不同的位置,因此实例完全更改将影响我的实现。我在演示代码中提供了更多细节;如果您可以通过并提出一些解决方法,那就太好了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2018-09-22
  • 1970-01-01
  • 2014-01-17
相关资源
最近更新 更多