以编程方式创建元素并重用代码

时间:2011-02-27 01:41:26

标签: iphone objective-c ios memory-management

我需要以编程方式创建多个按钮和标签。在大多数情况下,它们将具有相同的属性(opaque,backgroundColor,textColor),但文本,标记和框架除外。

在尝试限制我需要键入的代码量时,我认为这样可行:

// generate generic properties for our buttons
UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
tempButton.opaque = true;
tempButton.backgroundColor = [UIColor whiteColor];
tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
[tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
[tempButton addTarget:self action:@selector(handleButtonTap:) forControlEvents:UIControlEventTouchUpInside];

// generate specific button1 properties, assign to ivar, and display
tempButton.frame = CGRectMake(81, 136, 159, 37);
tempButton.tag = BUTTON_1_TAG;
[tempButton setTitle:@"button 1 title" forState:UIControlStateNormal];
self.button1 = tempButton;
[self.view addSubview:self.button1];

// generate specific button2 properties, assign to ivar, and display
tempButton.frame = CGRectMake(81, 254, 159, 37);
tempButton.tag = BUTTON_2_TAG;
[tempButton setTitle:@"button 2 title" forState:UIControlStateNormal];
self.button2 = tempButton;
[self.view addSubview:self.button2];

正如大多数人所知,只显示最后一个按钮。我认为这是因为我正在做的就是覆盖tempButton。

是否有一个解决方案可以让我完成我在这里尝试做的事情,而不必为每个元素创建单独的“临时”变量?

此外,上面的代码似乎会出现内存泄漏问题。我的理解是tempButton最初是自动释放的,但每次我用它来设置我的ivar时,是不是它再次被保留?在这样做之后,我是否需要向tempVar发送一个释放,以便它返回到1,这样当触发自动释放时,它实际上会被释放?

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

您可以创建一个构建“tempButton”的方法。

- (UIButton *)createTempButton {
    UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    tempButton.opaque = true;
    tempButton.backgroundColor = [UIColor whiteColor];
    tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
    [tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
    [tempButton addTarget:self action:@selector(handleButtonTap:) forControlEvents:UIControlEventTouchUpInside];
    return tempButton;
}

然后你可以在需要新的“tempButton”时调用它。

UIButton *aTempButton = [self createTempButton];

答案 1 :(得分:2)

1。)您正在为临时变量分配新的UIButton。这只是一项任务。赋值不会保留,因此您没有内存泄漏。

2.。)您可以创建一个返回部分配置按钮的方法,然后只需设置不同的部分:

- (UIButton *)myButton {
  UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  tempButton.opaque = true;
  tempButton.backgroundColor = [UIColor whiteColor];
  tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
  [tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
  return tempButton;
}


....
IButton *tempButton = [self myButton];
[tempButton setTitle:@"button 1 title" forState:UIControlStateNormal];
tempButton.frame = CGRectMake(81, 136, 159, 37);
[self.view addSubview:tempButton];
tempButton = [self myButton];
tempButton.frame = CGRectMake(81, 254, 159, 37);
[tempButton setTitle:@"button 2 title" forState:UIControlStateNormal];
[self.view addSubview:tempButton];

由于您已经为按钮指定了唯一标记,因此您无需分配给self.button1,self.button2等iVA,您只需使用[self.view viewForTag:]来检索正确的子视图。

但是,正如另一个人所说,如果你使用'self.button1 =',按钮会被保留,你需要释放你的dealloc,并担心调用 - [view didUnload] - 如果你不在那里发布,那么你将指向不再在视图中的按钮。

答案 2 :(得分:0)

  1. 您必须创建单独的按钮对象。由于UIButton不符合NSCopying协议,因此没有更简单的方法。如果要创建多个,请编写一个创建按钮的方法,设置公共属性并返回该对象。另一种方法是创建一个Nib文件并创建实例。

  2. self.button = ...会保留您的按钮吗?是的,如果物业的设定者保留它。当视图ID被卸载或取消分配时,您必须释放它。

答案 3 :(得分:0)

在:

self.button1 = tempButton;

button1属性可以是copy属性而不是retain属性。然后对tempButton的任何进一步更改都不会影响button1 ivar所持有的对象副本。 tempButton的保留计数也不会受到影响,所以你可以在初始化时释放它。