属性修饰符

2018-10-17
@property (copy) NSMutableArray *array 有什么问题

没有指明nonatomic,因此就是atomic原子操作,会影响性能。该属性使用了同步自旋锁,会在创建时生成一些额外的代码用于编写多线程程序,这会带来性能问题,通过声明nonatomic可以节省这些不必要的额外开销,因为就算使用了automic也不能保证绝对的线程安全,对于要绝对保证线程安全的操作,我们还需要使用更加高级的方式来处理,笔触NSSpinLock 或 @syncronized等
由于这里使用的是copy,所以得到的实际是NSArray类型,它是不可变的,若在使用中使用了增删改方法会crash;
链接1属性修饰符官方文档

copy关键字

通过一下代码打印NSMutableArray和NSArray类所包含的方法

 unsigned int count_f =0;
    //获取方法链表
    Method* methodList_f = class_copyMethodList([NSMutableArray class],&count_f);
    for(int i=0;i

查找copyWithZone方法可见NSMutableArray类并没有实现copyWithZone方法,所以NSMutableArray和NSArray的copyWithZone方法的实现是相同的。
链接2copy关键字的使用这篇文章比较详细。对于后面的部分还是做了些实验。

    NSString * str = @"str";
    NSMutableString * muStr = [NSMutableString stringWithFormat:@"mustr"];
    NSMutableString * str1 = [str copy];
    NSMutableString * str2 = [str mutableCopy];
    NSMutableString * str3 = [muStr copy];
    NSMutableString * str4 = [muStr mutableCopy];
(lldb) e str
(__NSCFConstantString *) $0 = 0x00000001000e87f0 @"str"
(lldb) e muStr
(__NSCFString *) $1 = 0x0000000174261940 @"mustr"
(lldb) e str1
(__NSCFConstantString *) $2 = 0x00000001000e87f0 @"str"
(lldb) e str2
(__NSCFString *) $3 = 0x00000001742615c0 @"str"
(lldb) e str3
(NSTaggedPointerString *) $4 = 0xa0000727473756d5 @"mustr"
(lldb) e str4
(__NSCFString *) $5 = 0x0000000174261a80 @"mustr"
(lldb) e [str4 appendString:@""];
(lldb) e [str3 appendString:@""];
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
(lldb) e [str2 appendString:@""];
(lldb) e [str1 appendString:@""];
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.
(lldb) e [muStr appendString:@""];
(lldb) e [str1 appendString:@""];
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.
(lldb) 

链接2中的文章后面说是非集合类的,所以又做了下面的实验

    NSArray * arr = @[@0];
    NSMutableArray * muArr= [NSMutableArray arrayWithObject:@1];
    NSMutableArray * arr1 = [arr copy];
    NSMutableArray * arr2 = [arr mutableCopy];
    NSMutableArray * arr3 = [muArr copy];
    NSMutableArray * arr4 = [muArr mutableCopy];
(lldb) e arr
(__NSSingleObjectArrayI *) $0 = 0x000000017401fa70 @"1 element"
(lldb) e muArr
(__NSArrayM *) $1 = 0x0000000174248ee0 @"1 element"
(lldb) e arr1
(__NSSingleObjectArrayI *) $2 = 0x000000017401fa70 @"1 element"
(lldb) e arr2
(__NSArrayM *) $3 = 0x0000000174248e20 @"1 element"
(lldb) e arr3
(__NSSingleObjectArrayI *) $4 = 0x000000017401faa0 @"1 element"
(lldb) e arr4
(__NSArrayM *) $5 = 0x0000000174248dc0 @"1 element"
(lldb) e [arr1 addObject:@3]
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
(lldb) e [arr2 addObject:@3]
(lldb) e [arr3 addObject:@3]
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.
(lldb) e [arr4 addObject:@3]
(lldb) 

通过以上实验可总结

  • copy返回的是不可变的
  • mutableCopy返回的是可变的
  • 可变的定为深复制
  • 可变性和原来不一样,定为深复制
  • copy并且可变性一样为浅复制

@property的本质是什么?ivar、getter、setter是如何生成并添加到这个类中的
@protocol和category中如何使用@property
assign、retain和copy的区别
iOS中assign与weak,retain与strong的区别

你可能感兴趣的:(属性修饰符)