iOS property中使用的copy、strong修飾的區別

#import <Foundation/Foundation.h>


@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。結果就是內存泄漏。









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章