2013-02-12 167 views
0

我試圖將我的一些「超級對象」分解爲具有單一(或至少有限)責任的更易於管理的類。創建另一個類的實例

我剛剛遇到的一個問題是創建一個UIBarButtonItem的特定實例的對象。在這個類中,現在我首先定義一個UIButton,然後將所有用作該子按鈕圖標的圖像作爲子視圖(例如,該按鈕表示對設備的訪問/控制,並使用按鈕圖像顯示該設備的當前信號強度)。此外,該按鈕正在偵聽來自設備對象的NSNotifications,以表示信號強度發生變化,或者設備斷開連接。按下按鈕會向設備發送信息以斷開連接。所有這些代碼現在作爲RootViewController的一個屬性工作得很好。但是,我想將它拉出到它自己的類中,因爲這個按鈕是由幾個類共享的,並且它只是用不必要的方法混淆了控制器。

我試着用下面的init來創建一個單獨的類。但是,這不起作用,因爲按鈕的自我不是最終由[UIBarButtonItem alloc]創建的同一個自我,並且當NSNotification或按鈕按下時嘗試向「自我」選擇器發送消息時, ,那個對象已經被處理了。問題是,我不知道如何創建一個對象(由類定義),它只是另一個類的實例,而不是對象的屬性(因爲它目前用於RootViewController)。

編輯和我的問題的補充說明

MyClass的是目前的UIBarButtonItem的子類。但是,我並沒有試圖像這樣使用它:[[MyClass alloc] initWithCustomView:]。我希望[MyClass alloc] init]自己完全創建自定義視圖 - 換句話說,這個類的全部內容是完全包含這個按鈕創建自己所需的全部內容,管理其子視圖並採取適當的操作當它被按下時。 (我可以用MyClass setupButton這樣的公共方法和一個類型爲UIBarButtonItem的公共方法輕鬆地讓MyClass成爲一個NSObject。但是,我認爲這看起來不對,因爲這個類只用於創建按鈕,但它不是按鈕本身)。

@interface MyClass : UIBarButtonItem 
@end 

@implementation MyClass 
- (id)init { 
    if (self = [super init]) { 

     UIImage *defaultButton = [[UIImage imageNamed:@"... 
     UIImage *defaultButtonPressed = [[UIImage imageNamed:@".... 
     UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 30)]; 
     [button setBackgroundImage:defaultButton forState:UIControlStateNormal]; 
     [button setBackgroundImage:defaultButtonPressed forState:UIControlStateHighlighted]; 
     [button addTarget:self action:@selector(deviceButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 

     //Then several UIImageViews that are added as subviews of the button, initially hidden 

     //Then set up the NSNotification listener 

     //Finally 
     self = [[UIBarButtonItem alloc] initWithCustomView:button]; 
    } 

    return self; 
} 

//Then several functions to handle hiding and unhiding the subviews depending on the received device notifications, and a function to handle the button press and sending the message back to the device. 

回答

1

這不是初始化在Cocoa中的工作方式。請在Cocoa Core Competencies指南中閱讀"Initialization"

當此init方法運行時,您的對象已被分配。您不應該將self指針重新分配給另一個分配。

你的班級首先應該調用其超類的指定初始化程序self = [super initWithWhatever:obj];,然後設置自己的屬性。

+0

謝謝,我確實意識到這一點。我想要做的是找出MyClass類型爲UIBarButtonItem的正確方法,並在創建它的實例時初始化它自己的自定義視圖。相信我,我意識到這個問題看起來有多簡單(這可能是我錯過了一些明顯的原因)。 – 2013-02-12 12:51:21

+0

嘗試用'[self setCustomView:button]'替換'self = [[UIBarButtonItem alloc] initWithCustomView:button];'' – 2013-02-12 19:12:04

+0

完美運作。我認爲'[super init]'可能會使它處於部分初始化狀態,但它可以工作。謝謝! – 2013-02-13 01:52:58

1

在我看來,要擴展UIBarButtonItem,在你init方法不能創建它的實例。嘗試從此改變你的類聲明(在類的.h文件中):

@interface MyClass : NSObject 

這樣:

@interface MyClass : UIBarButtonItem 

然後,只需在您的init方法返回self。將self設置爲一個值通常是一個糟糕的主意。

如果您不確定這裏發生了什麼,您將創建UIBarButtonItem的子類。這可以讓你的子類擴展超類的功能。如果你感到困惑,你應該看看面嚮對象語言中的繼承/類繼承,以瞭解發生了什麼。 This guide文檔Objective-C中的類如何工作。

+0

是的,我的聲明已經是「MyClass:UIBarButtonItem」。問題是,它不僅僅是UIBarButtonItem類型的擴展,它是特定的:initWithCustomView。這是我不確定如何去做的。如果我使用[[MyClass alloc] initWithCustomView:]這將是沒有問題的。但是,我想要包含在MyClass中並由其控制的自定義視圖。 – 2013-02-12 12:47:35

+0

@Adam如果你正在繼承'UIBarButtonItem',你完全可以避免使用'initWithCustomView:',並將你自定義視圖的邏輯移入子類本身。但是如果你真的需要使用它,你可以將if(self = [super init]){'segment改爲if(self = [super initWithCustomView:myView]){'。 – 2013-02-12 14:41:24

+0

我現在無法測試它。但是,UIBarButtonItem沒有簡單的'init'。所以如果我要創建一個MyClass的實例,我不確定返回的'[super init]'的狀態是什麼。儘管'UIBarButtonItem'具有自定義視圖的屬性,但我有一種預感,即返回的[[super init]]可能處於無用狀態(因爲它沒有用類引用中給出的五個標準入口之一進行初始化)。但是,也許不是。我會測試一下。 – 2013-02-12 15:04:59

相關問題