2013-02-12 169 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

相关问题