2013-01-22 30 views
2

與其他語言一樣,我們可以在initialization期間創建對象並覆蓋對象中的方法。請幫助我我該怎麼辦?如何初始化一個對象並重寫目標c中的方法?

例如:

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 Framework類似,它使用處理程序在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 
} 

}

+1

卸下'【JAVA ],因爲答案與Java沒有任何關係。 –

+0

謝謝,它是真的;答案與java無關 –

+0

在Objective-C中,無論你何時子類化它都會被自動覆蓋,如果你想調用超類的方法,你需要調用[super method]; –

回答

0

不那麼容易在Objective-C中做,但這應該工作。它用它自己的實現取代doSomething方法DemoInitAndOverride並返回該類的新實例。但是請注意,一旦完成了這個新實現,對於全部類的新實例,不僅僅是單個實例,而是保持原位。

- (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; 
} 
+0

感謝@trojanfoe,實例的完整更改會對我的實現產生問題,因爲我正在使用對象和方法以及各個位置的多重啓動。我在演示代碼中提供了更多細節;如果你可以通過並建議一些方法來解決它,這將是偉大的 –

0

這是一個討厭的,我建議創建一個子類或其他東西。

這是你的答案,它基本上是一樣的,但在運行時。繼續在自己的風險:

導入這樣的:

#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]; 
+0

謝謝@Ismael。我對演示代碼進行了更改。如果你可以通過它,並建議我一些等效的實施或方法,它會很好。完整類的實例更改將使我的實現失敗。 –