在使用nib文件做界面开发的过程中,加载nib文件后,由于设置了outlet和delegate,出现了一些未能及时释放的引用和retain循环,最后结果当然可想而知,dealloc没有走到,内存一路高歌走上去了。

所以在使用的时候应该需要注意一些地方,及时的释放不必要的引用等

官方文档Memory Management Programming Guide中 Memory Management of Nib Objects一节指出,通过nib文件加载的文件retaincount为1并且是autorelease的,但是又特别指出在内存警告的时候需要做这样的动作。

- (void)viewDidUnload {

self.anOutlet = nil;

[super viewDidUnload];

}

并且在UIViewController的dealloc中也要处理

- (void)dealloc {

// Release outlets and set outlet variables to nil.

[anOutlet release], anOutlet = nil;

[super dealloc];

}

在mac桌面开发中是这样的情况:

The File’s Owner of a nib file缺省要去释放NIB资源及顶层的对象

NIB文件的全局拥有者是全局应用对象NSApp,但是当Cocoa应用终止时,nib中的顶层对象也没有自动获得dealloc消息,因为NSApp已经被析构了。换句话说,即使nib主文件中,你也不得不管理顶层对象的内存

实际上也不用担心,mac已经有两个特征可以帮助你了

NSWindow对象有一个isReleasedWhenClosed属性,设置为YES则关闭窗口对象时自动关闭相关对象

nib文件的拥有者是一个NSWindowController对象,那么他会调用NSDocument来管理一个NSWindowController的实例,会自动释放他管理的窗口的

所以现实情况就是虽然你要负责释放一个nib文件中的top-level对象,但是只要你的nib文件的owner是一个NSWindowController的实例,那么它会帮你释放的。如果你的一个对象加载了nib自身并且文件的拥有者并不是NSWindowController,那么你可以为nib中的对象定义outlets,这样你就可以在恰当的时候释放他们。如果你不想为每个对象都声明outlet,你也可以这样:

NSNib类的instantiateNibWithOwner:topLevelObjects: 方法来获得nib文件中的所有顶层对象。

可是IOS直到4.0以后的sdk才有和NSNib类似作用的类UINib,这个在官方的sample:AdvancedTableViewcells中就有使用的例子。

Cocoa 没有提供 nib unload的api,所以你要unload一个nib文件,基本上来说就是要关闭由nib文件创建的windows并释放top level的对象。

另外,

n  仔细设计对象的owner关系,避免retain循环。

n  我们常见的delegate往往是assign方式的属性而不是retain方式 的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a, 如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。

n  类似NSArray, NSDictionary, NSSet 等类,会在对象加入后引用计数加一获得所有权,在对象被移除或者整个容器对象被释放的时候释放容器内对象的所有权。类似的情况还有UIView对 subview的所有权关系,UINavigationController对其栈上的controller的所有权关系等等。

n  还有一些用法会让系统拥有对象的所有权。比如NSObject 的performSelector:withObject:afterDelay 。如果有必要,需要显示的调用cancelPreviousPerformRequestsWithTarget:selector:object: ,否则有可能产生内存泄露。因这种原因产生的泄露因为并不违反任何规则,是Intrument所无法发现的。

UINib的类结构也是比较简单的。

分享到: 

iphone开发中使用nib(xib)文件的内存管理的更多相关文章

  1. iphone 开发中使用zbar时遇到的几个典型问题解决方法。

    iphone 开发中使用zbar时遇到的几个典型问题解决方法.   在近期的一个ios项目中使用到了一个二维码扫描库(Qrcode)--ZBar, 期间遇到2个问题.   1. zbar下载后使用其l ...

  2. 在iPhone开发中实现解压缩gzip

    在iPhone开发中实现解压缩gzip是本文要介绍的内容,最近做的一个东西中,需要从网络获取xml文件,但是该文件用了gzip压缩的.搜索一 下有人说gzip压缩的用urlrequest可以自己解压, ...

  3. iPhone开发中从一个视图跳到另一个视图有三种方法:

    iPhone开发中从一个视图跳到另一个视图有三种方法:   1.self.view addSubView:view .self.window addSubView,需要注意的是,这个方法只是把页面加在 ...

  4. iPhone开发中,关于视图跳转的总结(转)

    iPhone开发中,关于视图跳转的总结 iPhone开发中从一个视图跳到另一个视图有三种方法: 1. self.view addSubView:view .self.window addSubView ...

  5. iphone开发中调用系统打电话功能

    iphone开发中调用打电话功能,一般有2种: 1.系统的打电话代码,不返回当前程序: Java代码 [[UIApplication sharedApplication] openURL:[NSURL ...

  6. iPhone开发中的技巧整理

    1.NSCalendar用法 -(NSString *) getWeek:(NSDate *)d { NSCalendar *calendar = [[NSCalendar alloc] initWi ...

  7. iphone开发中数据持久化之——属性列表序列化(一)

    数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...

  8. 读书笔记-详解C程序开发中 .c和.h文件的区别

    一个简单的问题:.c和.h文件的区别 学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼: 子程序不要定 ...

  9. iphone开发中数据持久化之——嵌入式SQLite(三)

    前两篇分别讨论了使用属性列表的数据持久化.使用对象归档的数据持久化,本文将讨论第三个实现数据持久化的方法---嵌入式SQL数据库SQLite3.SQLite3在存储和检索大量数据方面非常有效.它还能够 ...

随机推荐

  1. Python - 基本数据类型及其常用的方法之元组

    元组 特点:一级元素无法被修改,且不能被增加或者删除. 基本操作: tu = (11, 22, ["aiden", 33, ("qwe", 11)], 77) ...

  2. C#——找出实现某个接口的所有类 - Hello World - CSDN博客

    原文:C#--找出实现某个接口的所有类 - Hello World - CSDN博客 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u0125260 ...

  3. 【xlwings1】多线程写入excel数据

    #!/ufr/bin/env python # -*- coding:utf-8 -*- import xlwings as xw import queue import threading impo ...

  4. PHP拓展 - xhprof性能分析工具

    Windows安装 参考:https://www.cnblogs.com/buexplain/p/4821619.html dll文件下载:https://windows.php.net/downlo ...

  5. jQuery 源码解析(二十九) 样式操作模块 尺寸详解

    样式操作模块可用于管理DOM元素的样式.坐标和尺寸,本节讲解一下尺寸这一块 jQuery通过样式操作模块里的尺寸相关的API可以很方便的获取一个元素的宽度.高度,而且可以很方便的区分padding.b ...

  6. UML类图解释

    那个动物矩形框,它就代表一个类(Class).类图分三层,第一层显示类的名称,如果是抽象类,则就用斜体显示.第二层是类的特性,通常是字段和属性.第三层是类的操作,通常是方法或行为.注意前面的符号,“+ ...

  7. JavaScript 对象的所有方法名称转换为大写

    function A() { this.do1 = function () { console.log(1); }; this.do2 = function () { console.log(2); ...

  8. cron服务

    相对与at,cron的优点就是能够周期性的执行某个命令,at却只能执行一次,cron的后台进程名字是crond ,cron也是system V的服务,所以我们可以service crond start ...

  9. redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法

    redis范围查询应用. 需求 根据IP找到对应的城市 原来的解决方案 oracle表(ip_country): 查询IP对应的城市: 1.把a.b.c.d这样格式的IP转为一个数字,例如为把210. ...

  10. Fitnesse批量读取变量信息,并保存到用例执行上下文中

    Fitnesse变量可以分成两种,一种是自定义变量,另一种是用例执行过程中的临时变量. 在Finesse使用过程中,如果需要定义一些公共的变量,可以统一在一个文件中使用自定义变量的方法,将公共变量全部 ...