一个UI控件弱引用问题

Posted syd_programming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个UI控件弱引用问题相关的知识,希望对你有一定的参考价值。

今天学习的过程中看到如下代码:


@interface ViewController ()
@property (weak,nonatomic) UIButton *buttonA;
@property (weak,nonatomic) UIButton *buttonB;
@property (strong,nonatomic) UILabel *theLabel;

- (void)initInterface;
- (void)updateInterface;
- (void)handleButton:(id)sender;
@end


@implementation ViewController
<p class="p1"><span class="s1">- (</span><span class="s2">void</span><span class="s1">)initInterface </span></p><p class="p2"><span class="s3">    </span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonA</span><span class="s3"> =[</span><span class="s5">UIButton</span><span class="s3"> </span><span class="s1">buttonWithType</span><span class="s3">:</span><span class="s1">UIButtonTypeRoundedRect</span><span class="s3">];</span></p><p class="p2"><span class="s3">    [</span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonA</span><span class="s3"> </span><span class="s1">addTarget</span><span class="s3">:</span><span class="s2">self</span><span class="s3"> </span><span class="s1">action</span><span class="s3">:</span><span class="s2">@selector</span><span class="s3">(handleButton:) </span><span class="s1">forControlEvents</span><span class="s3">:</span><span class="s1">UIControlEventTouchDown</span><span class="s3">];</span></p><p class="p2"><span class="s3">    [</span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonA</span><span class="s3"> </span><span class="s1">setTitle</span><span class="s3">:</span><span class="s6">@"Button A"</span><span class="s3"> </span><span class="s1">forState</span><span class="s3">:</span><span class="s1">UIControlStateNormal</span><span class="s3">];</span></p><p class="p3"><span class="s1">    </span></p><p class="p2"><span class="s3">    </span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonB</span><span class="s3"> =[</span><span class="s5">UIButton</span><span class="s3"> </span><span class="s1">buttonWithType</span><span class="s3">:</span><span class="s1">UIButtonTypeRoundedRect</span><span class="s3">];</span></p><p class="p2"><span class="s3">    [</span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonB</span><span class="s3"> </span><span class="s1">addTarget</span><span class="s3">:</span><span class="s2">self</span><span class="s3"> </span><span class="s1">action</span><span class="s3">:</span><span class="s2">@selector</span><span class="s3">(handleButton:) </span><span class="s1">forControlEvents</span><span class="s3">:</span><span class="s1">UIControlEventTouchDown</span><span class="s3">];</span></p><p class="p2"><span class="s3">    [</span><span class="s2">self</span><span class="s3">.</span><span class="s4">buttonB</span><span class="s3"> </span><span class="s1">setTitle</span><span class="s3">:</span><span class="s6">@"Button B"</span><span class="s3"> </span><span class="s1">forState</span><span class="s3">:</span><span class="s1">UIControlStateNormal</span><span class="s3">];</span></p><p class="p3"><span class="s1">    </span></p><p class="p1"><span class="s1">    </span><span class="s2">self</span><span class="s1">.</span><span class="s4">theLabel</span><span class="s1">=[</span><span class="s5">UILabel</span><span class="s1"> </span><span class="s7">new</span><span class="s1">];</span></p><p class="p4"><span class="s3">    </span><span class="s2">self</span><span class="s3">.</span><span class="s4">theLabel</span><span class="s3">.</span><span class="s5">text</span><span class="s3">=</span><span class="s1">@"Welcome"</span><span class="s3">;</span></p><p class="p5"><span class="s3">    [</span><span class="s2">self</span><span class="s3"> </span><span class="s1">updateInterface</span><span class="s3">];</span></p><p class="p1"><span class="s1"></span></p>

@end


同是UI控件,作者将button设为weak的,而label却是strong的,在updateInterface方法中我们看到button和label都被初始化,可为什么一个是strong另一个却是weak呢?

仔细观察initInterface方法我们发现他们使用的初始化方法是不同的,button用的是buttonWithType方法,而label用的是new方法。

先来说label,因为new方法分配的对象必须被一个指针强引用,否则在执行完这句代码后对象就 会因为没有被强引用而释放掉,因此label必须是强类型的。那button是弱类型的话难道对象不会被释放吗?问题就出在这个buttonWithType方法上。

根据ARC规则,所有非alloc/new/copy等开头的方法返回的对象都是autorelease的(参见点击打开链接 ),因此buttonWithType方法返回一个autorelease对象,即使不被任何对象所强引用,它也不会立即释放,而是要等runloop结束后才释放。因此

self.buttonA =[UIButton buttonWithType:UIButtonTypeRoundedRect];
之后self.buttonA指向的内存依然存在,使用没有问题。

以上是关于一个UI控件弱引用问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的应用程序在为 ui 元素分配弱引用时崩溃?

__strong和__weak

ThreadLocal为什么要使用弱引用和内存泄露问题

ThreadLocal为什么要使用弱引用和内存泄露问题

java中弱引用是怎么回事啊?

强引用strong和弱引用weak的定义