【问题标题】:Create elements programmatically and reuse code以编程方式创建元素并重用代码
【发布时间】:2011-07-05 02:10:55
【问题描述】:

我需要以编程方式创建几个按钮和标签。在大多数情况下,它们将具有相同的属性(不透明、背景颜色、文本颜色),但文本、标签和框架除外。

在尝试限制我需要输入的代码数量时,我认为这会起作用:

// 为我们的按钮生成通用属性 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]; // 生成具体的button1属性,赋值给ivar,并显示 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]; // 生成具体的button2属性,赋值给ivar,并显示 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,这样当触发自动释放时,它实际上会被释放?

感谢您的帮助!

【问题讨论】:

    标签: iphone objective-c ios memory-management


    【解决方案1】:

    您可以创建一个方法来构建您的“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];
    

    【讨论】:

    • 感谢您的快速回复。为什么我们在方法结束时自动释放它?是不是 tempButton 已经设置为自动释放,因为它是用类方法实例化的?
    • 如果它返回一个自动释放的对象,不要称它为“createTempButton”。这是难以发现的错误的秘诀:遵循 Cocoa 命名约定。
    • 你建议怎么称呼它?
    【解决方案2】:
    1. 您必须创建单独的按钮对象。由于 UIButton 不符合 NSCopying 协议,因此没有更简单的方法。如果你做了很多,写一个方法来创建一个按钮,设置公共属性并返回对象。另一种方法是制作 Nib 文件并制作实例。

    2. self.button = ... 是否保留您的按钮?是的,如果该属性的设置器保留它。当视图 ID 被卸载或解除分配时,您必须释放它。

    【讨论】:

      【解决方案3】:

      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] --如果您不在那里释放,那么您将拥有指向不再出现在视图中的按钮的指针。

      【讨论】:

      • 哦,viewForTag。我喜欢。让事情变得简单多了。您在上面的评论中提到了 Cocoa 命名约定。标签是否有标准约定,如果没有,你有自己的吗?
      • 我认为您的意思是 viewWithTag。找不到任何对 viewForTag 的引用。
      【解决方案4】:

      在:

      self.button1 = tempButton;
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 2011-10-05
        相关资源
        最近更新 更多