您的位置:首页 > 移动开发 > IOS开发

iOS开发:关键字说明

2016-05-26 21:30 330 查看
一、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;
}
为什么建议UI控件一般使用weak?

首先我们从controller来看,controller是被系统用强指针引用着,所以如果 controller 还存在,里面的子控件也会存在,

那么controller 强引用着它的view
(从 controller 中它的 view 的属性是 retain 看出来的,retain 就是 MRC 年代的强引用)


那么 view 又强引用着它的数组对象subviews,

数组对象又引用着它所包含的数组内容,

所以当我们创建出来一个UI控件并将其加入到subviews的时候,它就会被一个强指针所引用着,

我们可以简化一下这个过程:
--> Controller --> View --> Subviews(数组) --> 数组内容(添加到其中的UI控件)




清楚了过程之后,我们来看我们所创建的对象,如果我们所创建的是一个
临时变量
的话,那么当出去作用域之后对象就被销毁,

但是这里请注意,这里分为两个内存空间,一个是对象的内存空间,一个是指针的内存空间,

如果创建的是临时变量的话,一旦出了作用域那么我们的指针内存是被清空了,但是我们的内容如果加到了subviews中,就会被subviews强引用,那么我们的控件就还会存在,只不过是指向它的指针被清空了而已。

我们说说全局变量,全局变量的话,指针会一直存在,这里面谈谈为什么要用weak,其实只要我们创建的控件加入到subviews中去的话,那么这个控件就会一直存在,所以在这里我们所创建的指针是weak或strong其实只不过是多一个实线虚线的问题,也就是控件已经被强引用了,你再给它添加一个强引用或者弱引用在使用上都不会有什么问题。
但是问题来了,如果我们remove了这个控件,我们subViews中的那根线被切断,也就是这个代表我不再需要这个控件了,那么这个时候如果再用一个strong来连接它,那么对象就不会被清除,既然我们都不需要它了,为什么我还强引用它?
这也就是为什么我们再这里用弱引用的原因。`简言之,就是内存使用上的合理性,当这个控件我们需要的时候其实已经有一个强引用在引用着它,我们没有必要再弄一根指针来强引用着它,当我们不需要它的时候,如果是weak的话自然而然直接释放掉了,如果strong的话还会保留它,既然我们没用了我们为什么还要留着它而占用我们宝贵的内存呢。

这里特殊说一下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的原因是在代码块里面我可能会使用一些本地变量。而block一开始是放在栈上的,只有copy后才会放到堆上。
如果不加copy属性,当其所在栈被释放的时候,这些本地变量将变得不可访问。一旦代码执行到block这段就会导致bad access。

三、id与instancetype http://blog.csdn.net/kuizhang1/article/details/18048829
四、synthesize与dynamic

@synthesize 是系统自动生成getter和setter属性声明。@synthesize 意思是,除非开发人员已经做了,否则由编译器生成相应的代码,以满足属性声明。

@dynamic 意思是由开发人员提供相应的代码:对于只读属性需要提供 setter,对于读写属性需要提供 setter 和getter。查阅了一些资料确定@dynamic的意思是告诉编译器,属性的获取与赋值方法由用户自己实现, 不自动生成。

五、#import    #include、@class有什么区别?#import<> 跟 #import”"又什么区别?

#import和#include都能完整地包含某个文件的内容,#import能防止同一个文件被包含多次
@class仅仅是声明一个类名,并不会包含类的完整声明;@class还能解决循环包含的问题
#import <> 用来包含系统自带的文件,#import “”用来包含自定义的文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios开发