iOS property中使用的copy、strong修饰的区别

#import


@interface Animals : NSObject


@property(nonatomic,strong) NSString *strongMonkey;


@property(nonatomic,copy) NSString *monkey;


@end

测试如下:

- (void)viewDidLoad {

    [super viewDidLoad];

    

    NSMutableString *defaultName = [NSMutableString stringWithFormat:@"猴子"];

    

    Animals *animal = [Animals new];

    

    animal.monkey = defaultName;//生成一份新的内存空间

    animal.strongMonkey = defaultName;//指针指向同一块内存空间

    

    NSLog(@"%@,%@",animal.monkey,animal.strongMonkey);

    

    [defaultName appendString:@"吃鸡"];

    

    NSLog(@"更改后:%@,%@",animal.monkey,animal.strongMonkey);

    

}

注:在strong情况下,如果外部被引用的变量更改了,那里面这个值也会更改,因为两个属性指向同一块内存空间 。在这里strong 属于浅拷贝,只赋值对象的指针。
为了防止外界修改monkey,就用copy,因为copy是生成了一份新的内存空间,所以外界是不能修改值。

打印结果:

      猴子,猴子

更改后:猴子,猴子吃鸡

@property声明 NSString、NSArray、NSDictionary 会使用到copy关键字,他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在赋值操作时拷贝一份。
        strong  ---- 这个属性有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。
        copy    ---   经常用此特质来保护其封装性。因为传递给该属性的新值有可能指向一个NSMutable类的实例,若是不拷贝,那么设置完属性之后,可变类实例的值就可能会在对象不知情的情况下遭人更改。

附:Block属性声明为什么用copy来修饰 

  首先,你必须要对(堆栈)有一定的理解。 block声明后是放在栈里的,只有copy后才会放在堆上。当栈里的block被释放掉的时候,本地变量将变得不可访问,一旦代码执行到block这段就会导致崩溃。

     

ChangPhoneNumberController *vc = [[ChangPhoneNumberController alloc] init];

            vc.changBackBlock = ^{

                [self getUserinfo];

            };

            [self.navigationController pushViewController:vc animated:YES];

像这种block内部使用到的self当vc对象释放掉的时候,引用到的self也会被释放。而下面这种

__weak typeof(self) weakSelf = self;

 _registView.registNextStepBlock = ^{

       [weakSelf selectRegistSecond];

    };

如果将改为weakSelf改为self 很可能会导致循环引用。self持有registViewregistView持有registNextStepBlockregistNextStepBlock持有self。结果就是内存泄漏。









你可能感兴趣的:(OC的理解)