具有可选IBOutlet的属性多态性

时间:2014-12-29 15:53:48

标签: ios objective-c oop memory-management properties

我的iOS项目中有一个UITableViewCells的多态链(简化问题):

   ====================
  | BaseCellWithButton |
   ====================
            ^
            |
            |
 ========================
| BaseCellWithTwoButtons |
 ========================

BaseCellWithButton有1个属性:

@property (nonatomic, strong) UIButton* button;

BaseCellWithTwoButtons足够复杂,我想创建一个笔尖。我知道IBOutlet属性通常是(nonatomic, weak) IBOutlet ...,但我想将其声明为(nonatomic, strong) IBOutlet ...,以便我可以选择在nib中设置子类,但如果没有,我可以实例化它在父母。

这是一种不好的做法吗?有没有更好的方法来实现多态,同时允许子类创建一个nib并仍然重用父属性?

2 个答案:

答案 0 :(得分:2)

您可以在button课程中将IBOutlet声明为BaseCellWithButton,然后在任何子类中连接xib中的按钮。

enter image description here

我附加了示例文件,您可以将其添加到任何项目中,看看它是如何工作的。

有Base和Child类。

如果您计划通过父类

中的代码实例化它,那么strong引用也是最佳做法

在Base类中,声明了button但它仅在Child类中连接到xib https://dl.dropboxusercontent.com/u/48223929/SubclassTableCellsExample.zip

答案 1 :(得分:0)

声明属性弱或强的唯一显着区别在于为您合成的setter。您习惯于使用IBOutlets看到弱点,因为它们通常是UIView子类,它们被添加到其他视图中。将视图添加到另一个视图会将其放入一个数组(属于父视图的子视图数组),这会导致数组在对象上放置一个保留。

编辑感谢@nielsBot的评论,当他们指向的对象被释放/解除分配时,弱指针也自动设置为nil,这在我们使用时曾经是我们的问题分配而不是弱..所以如果你要使IBOutlet强大,那么你仍然需要在你的一个拆解方法中将指针设置为nil *

考虑这个

@interface someViewController()

@property (weak, nonatomic) UIButton *weakButton1, *weakButton2;
@property (strong, nonatomic) UIButton *strongButton1;

@end




@implementation someViewController

-(void ) viewDidLoad{

CGRect buttonRect = CGRectMake(20.0, 20.0, 250.0, 40.0 ) ;

self.weakButton1 = [[UIButton alloc] initWithFrame: buttonRect ];

//the following messages are passed to nil, because the weakButton1 pointer is weak,
// with no other retains the button was nilled out immediately...
// therefore we lose the button we created, it never make it to the view

[self.weakButton1 addTarget:self action: @selector (buttonAction: ) forEvent:UIControlEventTouchUpInside];
[self.view addSubView: self.weakButton1];

/////////////////////////////////////

self.strongButton1 = [[UIButton alloc] initWithFrame: buttonRect ];

//this one on the other hand works no problem

[self.strongButton1 addTarget:self action: @selector (buttonAction:) forEvent:UIControlEventTouchUpInside];
[self.view addSubView: self.strongButton1];

/////////////////////////////

UIButton *tempButton = [[UIButton alloc] initWithFrame: buttonRect ];

//button created into a scoped (temporary) pointer, which is strong by default, no problem...

[tempButton addTarget:self action: @selector (buttonAction:) forEvent:UIControlEventTouchUpInside];
[self.view addSubView: tempButton];

//button is assigned to weak property AFTER it is added to view (which causes a retain), no problem
self.weakButton2 = tempButton;

///////////////////////
}
@end