UIButton - alloc initWithFrame: 与 buttonWithType:

Posted

技术标签:

【中文标题】UIButton - alloc initWithFrame: 与 buttonWithType:【英文标题】:UIButton - alloc initWithFrame: vs. buttonWithType: 【发布时间】:2011-06-05 21:08:53 【问题描述】:

给定(任意):

CGRect frame = CGRectMake(0.0f, 0.0f, 100.0f, 30.0f);

下面两个代码sn-ps有什么区别?

1.

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = frame;

2.

    UIButton *button = [[[UIButton alloc] initWithFrame:frame] autorelease];

【问题讨论】:

【参考方案1】:

我认为它们是等价的。哈哈!诡计问题你这个鬼鬼祟祟的小混混!

推理

    -buttonWithType: 返回一个自动释放的UIButton 对象。

    +[NSObject alloc] 默认标量实例变量为0,因此buttonType 应为0UIButtonTypeCustom

优点和缺点

    1234563发生)。

    另一方面,您也可以争辩说使用-initWithFrame 足够清晰和安全。此外,许多 Xcode 示例项目,例如“TheElements”和“BubbleLevel”,都使用这种方法。一个优点是您可以在应用程序主线程的运行循环耗尽其自动释放池之前显式释放UIButton。而且,这就是为什么我更喜欢选项 2。

【讨论】:

"-[NSObject init] 默认标量实例变量为 0" 不,实际上是 +alloc 将实例变量设置为 0。"所以 buttonType 应该为 0" 不,这取决于 @987654336 @(如果有这样的方法)可以。当然,它可能当前将其设置为 0 或未设置(在这种情况下为 0);但是由于没有记录该方法,因此他们将来可能会改变其行为。你无法保证它的作用。 我知道这是旧的,但我注意到你必须使用[UIButton buttonWithType:] 是你的按钮类型永远不会设置。此外,您已将 -buttonWithType 作为实例方法编写,它应该是类方法,因此您需要将 - 替换为 + 另外,如果你是子类化,你必须使用 initWithFrame 方法。【参考方案2】:

我强烈建议使用第一种方法 (+buttonWithType),因为这是指定按钮类型的唯一方法。

如果你+alloc-initWithFrame:buttonType 被设置为某个标准值(不确定哪个,这可能会在 SDK 的更高版本中更改)并且之后您无法更改类型,因为buttonType 属性是只读的。

【讨论】:

【参考方案3】:

主要的(也许是唯一的)区别在于内存管理:正如你所说,buttonWithType 返回一个自动释放的UIButton。这样您就不必担心释放它。另一方面,您不拥有它,因此您无法在需要时释放它(当然,如果您 drain 自动释放池除外)。 相反,显式调用[[UIButton alloc] initWithFrame:frame],您会动态分配您的按钮,因此您拥有它并负责释放它。 如果您出于某种原因打算保留按钮,那么也许您应该考虑第二种解决方案,但是如果像这种情况一样,您要立即自动释放它,那么两种创建按钮的方式之间没有太大区别。 .

【讨论】:

【参考方案4】:

两个选项相同,但我更喜欢选项 2,因为它可以处理内存管理

【讨论】:

【参考方案5】:

您可以使用第一个并执行“[按钮保留];”,这样您就永远不会丢失指针。

【讨论】:

【参考方案6】:

我浏览了UIButton 文档,在这里我找到了:

讨论 此方法是一个方便的构造函数,用于创建具有特定配置的按钮对象。如果您将 UIButton 子类化,则此方法不会返回您的子类的实例。 如果要创建特定子类的实例,则必须直接分配/初始化按钮

我想这就是诀窍。 alloc-initWithFrame 用于子类。

【讨论】:

以上是关于UIButton - alloc initWithFrame: 与 buttonWithType:的主要内容,如果未能解决你的问题,请参考以下文章

UIButton.layer.cornerRadius 不存在?

UIButton

Gradle:initwith 不适用于 minify 和 proGuard

iOS alloc popover 控制器导致崩溃

如何快速调用 initWith...

有许多“initWith”参数通常是不好的做法吗?