最近在自己做一个小程序,遇到了页面跳转的问题,然后上网一通乱搜,跳转的问题解决了,又有传值的问题。上面两个问题解决了,又发现内存比刚开始时多占用了2M,于是,各种内心纠结,想彻底

搞清楚strong 和 weak 在ARC下到底是怎么个意思,也顺便理清了页面跳转之间的一些联系。

下面开始进入正题:(程序使用了storyboard)

由于页面中使用了一个动态加载的tableview,所以没法在页面中拖segue来实现页面跳转,那么只能在代码中实现页面跳转了。

下面上一下页面跳转的小片段:

页面A的控制器代码 头文件

 @interface BKViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableview1; @property (strong, nonatomic) UIViewController *checkFT;
@property (weak, nonatomic) UIViewController *checkFTWeak;
@end

头文件中定义了3个属性,

第一个属性就是对应页面上的一个tableview没什么好说的了。

第二个属性:一个strong  的页面B的控制器变量

第三个属性:一个weak    的页面B的控制器变量

具体干什么,稍后再说

 @interface BKViewController ()
{
BOOL _isRegistNib;
NSDateFormatter *_shortDateFormatter;
NSArray *tableData; NSArray *kpType;//记账类型
int pushCount;//纪录跳转次数
}
@end @implementation BKViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UIBarButtonItem *btnRight = [[UIBarButtonItem alloc] initWithTitle:@"测试" style:UIBarButtonItemStylePlain target:self action:@selector(test)];
[self.navigationItem setRightBarButtonItem:btnRight]; _isRegistNib = NO;
_shortDateFormatter = [DateFormatterHelper getShortDateFormatter];
//资金类型数据加载
kpType = [NSArray arrayWithObjects:@"记账日期",@"记账类型",@"资金流动类型",@"费用科目",nil];
[self loadTableViewData];
self.tableview1.dataSource = self;
self.tableview1.delegate = self; pushCount = ;
}

上面这段代码主要关注pushCount这个变量,它记录从A页面跳往B页面的次数,初始化为1

ok,准备工作完成了,下面说一下要实验的步骤:

1)从页面A 跳转到 页面B,跳转之前,将weak的 checkFTWeak 指针指向 页面B的对象;

2)然后回到页面A

3)点击测试按钮,测试一下 checkFTWeak现在指向的对象是否还存在

4)我们要有一个笼统的概念:strong会持有对象(引用计数+1),weak不会

代码:

 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
LycTableCellViewDefault *cell = (LycTableCellViewDefault *)[tableView cellForRowAtIndexPath:indexPath];*/ NSLog(@"当前跳转次数%i",pushCount);
//跳转到选择资金类型页面
if (indexPath.section == && indexPath.row == ) {
UIStoryboard *sbMain = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
CheckFlowTypeViewController *cv = [sbMain instantiateViewControllerWithIdentifier:@"checkFlowTypeSB"]; if (pushCount == ) {
self.checkFTWeak = cv;
}
NSLog(@"checkFTWeak指向的对象是%@", self.checkFTWeak);
pushCount++;
//[self presentViewController:cv animated:YES completion:nil ];
[self.navigationController pushViewController: cv animated:YES];
}
} -(void)test
{
NSLog(@"checkFTWeak指向的对象是%@", self.checkFTWeak);
}

首先初始化要跳转到的页面B对象 cv,然后将 checkFTWeak 指针指向 cv;接着就打印出对象的信息

当从B 跳回 到A时,点击A页面的测试按钮,再打印 checkFTWeak指针,看看它指向的对象还存在否

通过运行结果,我们看到,当页面从B 返回 A 之后,checkFTWeak指向的对象,也就是那个页面b不存在了。

那么如果让checkFT这个strong类型的属性指向页面b是什么结果呢?

修改tableview选中事件的那句代码为:self.checkFT = cv;

运行结果为:

可以看到,由于checkFT指针是strong类型的属性,那么他会持有页面B的对象,导致内存不会释放

结合上面两个例子,可以总结下面两点:

1)页面跳转时创建的目标页面(就是页面B),在返回后(也就是调用popViewController方法),将会被释放

2)明白了strong和weak的区别,

strong指向的对象不会被释放,除非把指针设置为nil;

而weak不会对指向的对象的引用计数有任何影响,在饮用对象不存在时,会返回nil,替我们做了处理;

那么到这里我还有一个疑问:如果strong类型的指针,本来指向 c,后来又指向d的话,那么c会被释放还是继续存在?

那么继续来改造代码,这个时候前面提到的pushCount参数就起作用了,具体试验步骤如下:

1)从页面A跳转到页面B,同时让checkFT、 checkFTWeak 两种类型的指针指向页面B的对象

2)返回后打印两个指针指向的对象

3)再次从页面A跳转到页面B,但是strong类型的 checkFT指针指向新初始化的页面B,checkFTWeak指针还是指向原来的那个对象

4)返回页面A,打印两个指针指向的对象

修改后的代码:

 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
LycTableCellViewDefault *cell = (LycTableCellViewDefault *)[tableView cellForRowAtIndexPath:indexPath];*/ NSLog(@"当前跳转次数%i",pushCount);
//跳转到选择资金类型页面
if (indexPath.section == && indexPath.row == ) {
UIStoryboard *sbMain = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
CheckFlowTypeViewController *cv = [sbMain instantiateViewControllerWithIdentifier:@"checkFlowTypeSB"];
self.checkFT = cv; if (pushCount == ) {
self.checkFTWeak = cv;
}
NSLog(@"checkFT指向的对象是%@",self.checkFT);
NSLog(@"checkFTWeak指向的对象是%@", self.checkFTWeak);
pushCount++;
//[self presentViewController:cv animated:YES completion:nil ];
[self.navigationController pushViewController: cv animated:YES];
}
} -(void)test
{
NSLog(@"点击测试按钮后:");
NSLog(@"checkFT指向的对象是%@",self.checkFT);
NSLog(@"checkFTWeak指向的对象是%@", self.checkFTWeak);
}

运行的结果:

第一次跳转因为有strong类型的指针checkFT给weak类型的指针checkFTWeak撑腰,所以他俩指向对象一样。

在返回页面A后,发生第二次跳转钱checkFT指向了新的页面B的对象,checkFTWeak指向的对象被释放了,所以打印出了nil

那么又得出了第三个结论:

当strong类型的指针从指向a变成指向b之后,原来的a对象的引用计数将会-1,如果没有其他指针持有它,它变被arc给释放了。然后b的引用计数会+1;

分析结束,如果不对之处希望指出共同学习。

 

ios基础之 透过页面跳转来认识 Strong 与 Weak的更多相关文章

  1. iOS内存管理retain,assign,copy,strong,weak

    转自:http://www.cnblogs.com/nonato/archive/2013/11/28/3447162.html iOS的对象都继承于NSObject, 该对象有一个方法:retain ...

  2. iOS推送后页面跳转

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  3. Android应用开发基础之六:页面跳转和数据传递

    创建第二个Activity 需要在清单文件中为其配置一个activity标签 标签中如果带有这个子节点,则会在系统中多创建一个快捷图标 <intent-filter> <action ...

  4. [iOS基础控件 - 6.12.3] @property属性 strong weak copy

    A.概念 @property 的修饰词   strong: 强指针/强引用(iOS6及之前是retain) weak: 弱智真/弱引用(iOS6及之前是assign)   默认情况所有指针都是强指针 ...

  5. iOS ARC下循环引用的问题 -举例说明strong和weak的区别

    strong:适用于OC对象,作用和非ARC中的retain作用相同,它修饰的成员变量为强指针类型weak:适用于OC对象,作用和非ARC中的assign作用相同,修饰的成员变量为弱指针类型assig ...

  6. php开发中的页面跳转方法总结

    PHP页面跳转实现的功能就是将网站中一个网页跳转到另一个网页中.对于刚刚学习PHP语言的朋友来说,是必须要掌握的基础方法. 页面跳转可能是由于用户单击链接.按钮等触发的,也可能是系统自动产生的.页面自 ...

  7. iOS Strong 和 weak

    iOS 5 中对属性的设置新增了strong 和weak关键字来修饰属性(iOS 5 之前不支持ARC) strong 用来修饰强引用的属性: @property (strong) SomeClass ...

  8. JS判断是否是微信页面,判断手机操作系统(ios或android)并跳转到不同下载页面

    JS判断客户端是否是iOS或者Android 参考:http://caibaojian.com/browser-ios-or-android.html function is_weixin() { v ...

  9. iOS——使用StroryBoard页面跳转及传值

    之前在网上搜iOS的页面跳转大多都是按回以前的那种xib的形式,但鄙人是使用storyboard的.这篇就只介绍利用storyboard进行页面跳转与传值. 新建页面 iOS的程序也是使用了MVC的思 ...

随机推荐

  1. HTTP基本认证

    众所周知,Web使人们可以很方便的访问分布在世界各个角落里信息.但是仅仅是方便还是不够的,并不是所有的信息都适合在互联网上公开访问,我们需要保证只有特定的人才能看到我们的敏感信息并且执行特定的操作. ...

  2. CentOs 7怎么联网

    在安装好Centos7后,网络还不能正常使用,需要我们手动配置.并且Linux的网络配置并不太容易,新手经常不知道从何开始.为了解决这个令大家头疼的问题,我在此将成功的配置过程与大家分享.希望大家都能 ...

  3. 关于实现一个基于文件持久化的EventStore的核心构思

    大家知道enode框架的架构是基于ddd+event sourcing的思想.我们持久化的不是聚合根的最新状态,而是聚合根产生的领域事件.最近我在思考如何实现一个基于文件的eventstore.目标有 ...

  4. TypeError: 'bases' is null or not an object。IE8 bug 腐朽的对象

    使用Webapp Builder时候发现,在IE8上很奇怪的一个现象:在ajax回调函数中引用一个闭包作用域链中的对象作为某一个Dijit的实例化参数时有问题:bases is null or not ...

  5. 冲刺阶段 day13

    ---恢复内容开始--- 项目进展 今天星期三,我们将专业管理部分又继续做了完善,之前漏掉的几项功也一一补全,没能实现的数据库部分也已经进行了完善,并且对已经完成的部分进行了检测,数据库的部分还有待进 ...

  6. 冲刺阶段 day11

    项目进展:系部,专业,班级管理这三项没有学生,教师管理部分输入项目多,所以窗体搭建比较简单,代码也简单一些,进行的还算顺利,有了之前的编写经验,很多代码可以直接copy过来,越进行编写越顺利了,已经进 ...

  7. 走进AngularJs(三)自定义指令-----(上)

    一.有感而发的一些话 在学习ng之前有听前辈说过,angular上手比较难,初学者可能不太适应其语法以及思想.随着对ng探索的一步步深入,也确实感觉到了这一点,尤其是框架内部的某些执行机制,其复杂程度 ...

  8. 用C表达面向对象语言的机制2——颠覆你对方法调用的看法!

    用C表达面向对象语言的机制2——颠覆你对方法调用的看法! 源代码在文末.推荐阅读本文PDF版,格式更好看. 在上一篇<用C表达面向对象语言的机制——C#版>中,我们获知了如何用C表达面向对 ...

  9. 一则JVM memory leak解决的过程

    起因是我们的集群应用(3台机器)新版本测试过程中,一般的JVM内存占用 都在1G左右, 但在运行了一段时间后,慢慢升到了4G, 这是一个明显不正常的现象. 定位 过程: 1.先在该机器上按照步骤尝试重 ...

  10. EF架构~在Linq to Entity中使用日期函數

    回到目录 眾所周知,在linq to entity的查询语句中,不允许出现ef不能识别的关键字,如Trim,Substring,TotalDays等.net里的关键字,在EF查询里都是不被支持的,它的 ...