一、static 关键字的作用
修饰局部变量:变量作用域不变,存储为静态存储,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值。
修饰全局变量:全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问。
二、属性关键字
@property是一个属性访问声明,扩号内支持以下几个属性:
1、getter=getterName ,设置getter的方法名。
2、setter=setterName, 设置setter的方法名。
3、readwrite,设置可供访问级别对应生成setter、getter方法。
4、readonly,设置可供访问级别对应生成getter方法。
5、assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题 。
6、retain,使引用对象的引用计数加1.
7、release,使引用对象的引用计数减1。
8、copy,复制出新对象,就对象的引用计数不变,新对象的引用计数加1。这是为了减少对上下文的依赖而引入的机制。使a和b各自有自己的内存。
9、nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。
10、atomic,原子性访问,不允许多线程访问,相当于加锁。
11、strong,强引用,引用对象的引用计数加1,相当于MRC下的retain。
12、weak,弱引用,引用对象的引用计数不变,相当于MRC下的assign。
@property (nonatomic,retain)NSString *name
- (void) setName:(NSString*) str
{
[str retain];
[name release];
name = str;
}
@property(nonatomic,copy)NSString *name
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}
首先我们从controller来看,controller是被系统用强指针引用着,所以如果 controller 还存在,里面的子控件也会存在,
那么controller 强引用着它的view(从 controller 中它的 view 的属性是 retain 看出来的,retain 就是 MRC 年代的强引用)
,
那么 view 又强引用着它的数组对象subviews,
数组对象又引用着它所包含的数组内容,
所以当我们创建出来一个UI控件并将其加入到subviews的时候,它就会被一个强指针所引用着,
我们可以简化一下这个过程:--> Controller --> View --> Subviews(数组) --> 数组内容(添加到其中的UI控件)
清楚了过程之后,我们来看我们所创建的对象,如果我们所创建的是一个临时变量
的话,那么当出去作用域之后对象就被销毁,
但是这里请注意,这里分为两个内存空间,一个是对象的内存空间,一个是指针的内存空间,
如果创建的是临时变量的话,一旦出了作用域那么我们的指针内存是被清空了,但是我们的内容如果加到了subviews中,就会被subviews强引用,那么我们的控件就还会存在,只不过是指向它的指针被清空了而已。
这里特殊说一下IBOutlet中的拖线创建,我们可以发现,如果用storyboard或者xib进行的脱线创建,苹果都会自动降属性置为weak,这种做法似乎也符合我们之前的说法,但是苹果又会在之前加了一个IBOutlet这个关键词,那么这个词是什么意思呢?我们看一下苹果的官网解释: The symbol IBOutlet is used only by Xcode, to determine when a property is an outlet; it has no actual value.
意思很清楚了,它仅仅是指定了一个属性是一个 外部设置的,并没有实质的含义,通常与外界连接是通过当前的 viewcontroller 。那么在引用上又有什么不同呢?在官方文档中是这么说的,在我们创建了IBOutlet之后,我们系统会有一个自动对它进行一个强引用,也就是又多了一条实线连接着它,当控件从我们的subviews中移除之后,这条线会自动判断去留,也就是不会对我们的内存的性能造成影响,该在的时候我在,该消失的时候自己就会消失了。这里也用一张图来说明:
我将block声明为copy的原因是在代码块里面我可能会使用一些本地变量。而block一开始是放在栈上的,只有copy后才会放到堆上。
如果不加copy属性,当其所在栈被释放的时候,这些本地变量将变得不可访问。一旦代码执行到block这段就会导致bad access。
@synthesize 是系统自动生成getter和setter属性声明。@synthesize 意思是,除非开发人员已经做了,否则由编译器生成相应的代码,以满足属性声明。
@dynamic 意思是由开发人员提供相应的代码:对于只读属性需要提供 setter,对于读写属性需要提供 setter 和getter。查阅了一些资料确定@dynamic的意思是告诉编译器,属性的获取与赋值方法由用户自己实现, 不自动生成。