国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

OC語言-08-深拷貝與淺拷貝詳解(示例)

2019-11-14 18:20:49
字體:
來源:轉載
供稿:網友

概述


  • 拷貝:復制一個與源對象內容相同的對象
  • 實現拷貝,需要遵守以下兩個協議

    • NSCopying
    • NSMutableCopying
  • 拷貝返回對象的種類

    • 可變,mutableCopy消息返回的對象
    • 不可變,copy消息返回的對象
  • 拷貝的種類

    • 淺拷貝,只是復制了一個指向源對象的指針,未創建對象,未分配內存
    • 深拷貝,復制了源對象,創建了新對象,分配了內存
  • 注意

    • 系統對容器類的對象與非容器類的對象的內存處理是不同的,即當一個沒有被其他對象強引用的對象從容器中移除后,該對象就銷毀

Copy與Retain


  • copy

    • 是創建一個新的對象,內容拷貝
    • copy表示的是兩個對象的內容相同, 新對象的引用計數為1
    • 與舊對象的引用計數無關,就對象沒有變化
    • copy減少了對象對上下文的
  • retain

    • 創建的是一個指針,指針拷貝
    • 對象地址相同,內容固然相同
    • 對象的引用計數+1

不同對象的拷貝行為


  • 非容器對象(如NSString))

    • 對于不可變對象

      • 規則

        • copy,淺拷貝(指針復制)
        • mutableCopy,深拷貝(對象復制),返回對象可變(產生新的 可變對象)
      • 示例

        - (void)imutableInstanceCopy{    NSString *string = @"Welcome to Xcode";    //copy,淺拷貝    NSString *stringCopy = [string copy];    //mutableCopy,返回的對象可變    NSMutableString *stringMutableCopy = [string mutableCopy];    [stringMutableCopy appendString:@"!"];    //string與stringCopy的內存地址相同    NSLog(@"string: %p", string);    NSLog(@"strongCopy: %p", stringCopy);    //string與stringMutableCopy的內存地址不同,分配了新的內存    NSLog(@"stringMCopy:%p", stringMutableCopy);}
    • 對于可變對象

      • 規則

        • copy,深拷貝(對象復制),返回對象不可變
        • mutableCopy,深拷貝(對象復制)
      • 示例

        - (void)mutableInstanceCopy{    NSMutableString *mutableString = [NSMutableString stringWithString: @"Welcome to Xcode"];    //深拷貝,返回對象不可變    NSString *stringCopy = [mutableString copy];    NSMutableString *mutableStringCopy = [mutableString copy];    //運行時,此句會報錯,錯誤信息“Attempt to mutate immutable object with appendString:”    [mutableStringCopy appendString:@"~~~"];    //深拷貝,返回對象可變    NSMutableString *stringMutableCopy = [mutableString mutableCopy];    [stringMutableCopy appendString:@"!"];    //三者與mutableString的內存地址都不同    NSLog(@"mutableString: %p", mutableString);    NSLog(@"string: %p", stringCopy);    NSLog(@"mutableStringCopy: %p", mutableStringCopy);    NSLog(@"stringMutbleCopy:%p", stringMutableCopy);}
  • 容器對象(NSArray

    • 遵循非容器對象的拷貝原則
    • 注意

      • 容器內的元素是指針賦值(淺拷貝)
      • 示例

        - (void)containerInstanceShallowCopy{    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil];    //淺拷貝    NSArray *arrayCopy = [array copy];    //深拷貝    NSMutableArray *arrayMutableCopy = [array mutableCopy];    NSLog(@"array: %p", array);    NSLog(@"arrayCopy: %p", arrayCopy);    NSLog(@"arrayMutableCopy: %p", arrayMutableCopy);    //容器內的對象是淺拷貝,即它們在內存中只有一份    NSMutableString *testString = [array objectAtIndex:0];    [testString appendString:@" you"];    //三個數組的內容同時改變    NSLog(@"array[0]: %@", array[0]);    NSLog(@"arrayCopy[0]: %@", arrayCopy[0]);    NSLog(@"arrayMutableCopy[0]: %@", arrayMutableCopy[0]);}
    • 實現真正意義上的深復制

      - (void)containerInstanceDeepCopy{    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil];    //數組內對象是指針復制    NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array];    //真正以上的深復制,數組內對象是對象復制    NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];    NSLog(@"array: %p", array);    NSLog(@"deepCopyArray: %p", deepCopyArray);    NSLog(@"trueDeepCopyArray: %p", trueDeepCopyArray);    //改變array的第一個元素    [[array objectAtIndex:0] appendString:@" you"];    //只影響deepCopyArray數組的第一個元素    NSLog(@"array[0]: %@", array[0]);    NSLog(@"arrayCopy[0]: %@", deepCopyArray[0]);    //不影響trueDeepCopyArray數組的第一個元素,是真正意義上的深拷貝    NSLog(@"arrayMutableCopy[0]: %@", trueDeepCopyArray[0]);}
  • 自定義對象

    • 在定義對象要實現拷貝,需要遵守NSCoping與NSMutableCoping協議,并實現以下方法

      • - (id)copyWithZone:(NSZone *)zone,可變拷貝
      • - (id)mutableCopyWithZone:(NSZone *)zone,不可變拷貝
    • 示例(自定對象Person的拷貝)

      • 遵守協議,設置成員屬性

        @interface Person : NSObject <NSCopying, NSMutableCopying>/**姓名*/@PRoperty (nonatomic, copy) NSMutableString *name;/**地址*/@property (nonatomic, copy) NSString *address;/**年齡*/@property (nonatomic, assign) NSInteger age;@end
      • 重寫初始化方法

        - (instancetype)init{    if (self = [super init])    {        self.name = [[NSMutableString alloc] initWithString:@"XiaoYaowang"];        self.address = @"世俗孤島";        self.age = 3;    }    return self;}
      • 實現- (id)copyWithZone:(NSZone *)zone

        - (id)copyWithZone:(NSZone *)zone{    Person *p = [[[self class] allocWithZone:zone] init];    p.name = [self.name copy];    p.address = [self.address copy];    p.age =  self.age;    return p;}
      • 實現- (id)mutableCopyWithZone:(NSZone *)zone

        - (id)mutableCopyWithZone:(NSZone *)zone{    Person *p = [[[self class] allocWithZone:zone] init];    //注意,此處是mutableCopy方法    p.name = [self.name mutableCopy];    p.address = [self.address copy];    p.age =  self.age;    return p;}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 尖扎县| 桂阳县| 林口县| 海阳市| 汉中市| 永嘉县| 雷山县| 永安市| 弥渡县| 曲水县| 清涧县| 微山县| 平远县| 都昌县| 苏州市| 木里| 肇东市| 平定县| 商水县| 大名县| 武威市| 通河县| 蒙自县| 齐河县| 灵宝市| 伊吾县| 朝阳县| 胶南市| 汤阴县| 烟台市| 商水县| 双城市| 白朗县| 蒲江县| 宝应县| 荥阳市| 洛南县| 将乐县| 安平县| 乌拉特后旗| 尖扎县|