@property相关的问题

来源:互联网 发布:淘宝c店铺 编辑:程序博客网 时间:2024/06/06 15:40

一.@property的本质是什么

property(属性) = ivar(实例变量) + access method(存取方法);
access method =  getter + setter;
property作为 OC 的一项特性,主要的作用就在于封装对象中的数据。 OC 对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问。

二.@synthesize和@dynamic分别有什么作用

1.@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;
2.@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
3.@dynamic告诉编译器:属性的setter与getter方法由用户自己实现,不自动生成。

三.为什么用@property声明NSString经常使用copy?如果改用strong,可能造成什么问题?

1.因为父类指针可以指向子类对象,使用copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.

2.如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.
用@property声明 NSString、NSArray、NSDictionary 经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。

四.@synthesize有哪些使用场景

1.同时重写了setter和getter时; 2.重写了只读属性的getter时;3.使用了@dynamic时;4.在 @protocol 中定义的所有属性;5.在 category 中定义的所有属性;6.重载的属性

五.@protocol和category中如何使用@property

1.在protocol中使用property只会生成setter和getter方法声明,我们使用属性的目的,是希望遵守协议的对象能实现该属性
2.category 使用 @property 也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行时的两个函数:objc_setAssociatedObject和objc_getAssociatedObject

六.什么情况下使用weak关键字,相比assign有什么不同

1.在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如:delegate代理属性
2.自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用weak,自定义IBOutlet控件属性一般也使用weak;当然,也可以使用strong。
不同点:
1.weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type),例如 CGFloat 或 NSlnteger 等)的简单赋值操作。
2.assigin 可以用非OC对象,而weak必须用于OC对象

七.__block和__weak修饰符的区别

  1. __block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 
  2. __weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。 
  3. __block对象可以在block中被重新赋值,__weak不可以。

八.delegate为什么用assign而不是strong

类与类之间的关系有继承和聚合,当我们使用聚合的时候该对象就拥有聚合的对象,这时候我们就需要使引用计数器+1来控制该对象的内存管理,所以strong和copy的一项能力就是拥有该对象的内存管理权。一个对象没必要管理自己delegate的生命周期,或者说没必要拥有该对象,所以我们只要知道它的指针就可以了,用指针找到对象去调用方法,也就是委托实现的感觉。

或者我们换个角度,从内存管理方面也可以解释这个问题。delegate的生命周期不需要让该对象去控制,如果该对象使用strong很可能导致delegate所指向的对象无法正确的释放。

九.强引用和弱引用的区别

1、 weak 和 strong 属性只有在你打开ARC时才会被要求使用,这时你是不能使用retain release autorelease 操作的,因为ARC会自动为你做好这些操作,但是你需要在对象属性上使用weak 和strong,其中strong就相当于retain属性,而weak相当于assign。
2、
只有一种情况你需要使用weak(默认是strong),就是为了避免retain cycles(就是父类中含有子类{父类retain了子类},子类中又调用了父类{子类又retain了父类},这样都无法release)    
3、
声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。
   

十.@property的主要关键字详解

1.atomic(原子性) 与 nonatomic(非原子性)[线程安全]
Objective-C中原子性就是为了保证线程安全而存在。如果当前的某一属性为原子性,那么任何一个线程对其记性set和get方法时都会对当前的属性进行加锁和解锁操作。从而保证其在多线程编程环境的线程安全。通常情况下,我们不会涉及过多的线程安全,并且加锁和解锁操作也会造成相当多的资源,所以我们一般都将属性设置为非原子性。但是苹果公司为了安全考虑出发,默认是原子性。
2.readwrite(读写) 与 readonly (只读) [访问控制]
属性默认情况下可以对实例变量进行取值和赋值的操作,其实质就是有set和get方法。只读的含义其实就是只有get方法,没有提供set方法。为了操作的方便,苹果将读写属性设置为实例变量的默认属性。
3.strong (强引用) 与 weak(弱引用) 与 assign(赋值) 与copy(复制)
strong表示属性对所赋的值持有强引用表示一种“拥有关系”(owning relationship),会先保留新值即增加新值的引用计数,然后再释放旧值即减少旧值的引用计数。只能修饰对象。如果对一些对象需要保持强引用则使用strong。
weak表示对所赋的值对象持有弱引用表示一种“非拥有关系”(nonowning relationship),对新值不会增加引用计数,也不会减少旧值的引用计数。所赋的值在引用计数为0被销毁后,weak修饰的属性会被自动置为nil能够有效防止野指针错误。 weak常用在修饰delegate等防止循环引用的场景。
assign主要用来修饰Objective-C中的基础属性。
copy修饰的属性会在内存里拷贝一份对象,两个指针指向不同的内存地址。 
一般用来修饰有对应可变类型子类的对象。 
如:NSString/NSMutableString,NSArray/NSMutableArray,NSDictionary/NSMutableDictionary等。 
为确保这些不可变对象因为可变子类对象影响,需要copy一份备份,如果不使用copy修饰,使用strong或assign等修饰则会因为多态导致属性值被修改。 copy还被用来修饰block,在ARC环境下编译器默认会用copy修饰, 一般情况下在block需要捕获外界数据时该block就会被分配在堆区,但在MRC环境下由于手动管理引用计数,block一般被分配在栈区,需要copy到堆区来防止野指针错误。




原创粉丝点击