IOS學(xué)習(xí)筆記十八(copy、mutableCopy、NSCopying、NSMutableCopy、深復(fù)制、淺復(fù)制)

1、 copy、mutableCopy方法

copy方法返回對象的不可修改的副本

mutableCopy方法返回的對象可修改的副本


1)、測試demo

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            NSMutableString *book = [NSMutableString stringWithString:@"chenyu"];
            NSMutableString *bookCopy = [book mutableCopy];
            [bookCopy replaceCharactersInRange:NSMakeRange(1, 2) withString:@"gong"];
            NSLog(@"book is %@", book);
            NSLog(@"bookCopy is %@", bookCopy);
            
            NSString *str = @"chenyu";
            NSMutableString *strCopy = [str mutableCopy];
            [strCopy appendString:@"chenyu"];
            NSLog(@"strCopy is:%@", strCopy);
            //由于str2是不可變的,所以運行下面會報錯
            NSMutableString *str2 = [str copy];
            NSLog(@"str copy chen is:%@", str2);
    //        [str2 appendString:@"chenyu"];
        }
    }


2)、運行結(jié)果


    2018-07-15 19:03:35.564049+0800 cyTest[27254:9418105] book is chenyu
    2018-07-15 19:03:35.565157+0800 cyTest[27254:9418105] bookCopy is cgongnyu
    2018-07-15 19:03:35.566056+0800 cyTest[27254:9418105] strCopy is:chenyuchenyu
    2018-07-15 19:03:35.566857+0800 cyTest[27254:9418105] str copy chen is:chenyu

 
2、NSCopying、NSMutableCopy協(xié)議
對象調(diào)用copy方法來復(fù)制自身的可變副本,需要類 實現(xiàn)NSCopying協(xié)議,讓該類實現(xiàn)copyWithZone方法

對象調(diào)用mutableCopy方法來復(fù)制自身的可變副本,需要類實現(xiàn)NSMutbaleCopying協(xié)議,讓類實現(xiàn)mutableCopyWithZone方法demo可以看下下面寫的淺復(fù)制

 
3、深復(fù)制和淺復(fù)制

我個人理解感覺淺復(fù)制是復(fù)制后的屬性(指針變量)指向的地址都是同一塊地址,當(dāng)復(fù)制后的對象屬性值發(fā)生變化的時候,原始值也發(fā)生了變化。

深復(fù)制就是復(fù)制后的屬性(指針變量)指向的地址不是同一塊地址,當(dāng)復(fù)制后的對象屬性值發(fā)生變化的時候,原始值不會發(fā)生變化。


1)、淺復(fù)制測試Demo

Dog.h

    #import <Foundation/Foundation.h>
    #ifndef Dog_h
    #define Dog_h
     
    @interface Dog : NSObject<NSCopying>
    @property (nonatomic, strong) NSMutableString *name;
    @property (nonatomic, assign) int age;
    @end
    #endif /* Dog_h */


Dog.m


    #import <Foundation/Foundation.h>
    #import "Dog.h"
     
    @implementation Dog
    @synthesize name;
    @synthesize age;
    -(id)copyWithZone:(NSZone *)zone
    {
        Dog *dog = [[[self class] allocWithZone:zone] init];
        dog.name = self.name;
        dog.age = self.age;
        return dog;
    }
    @end

 
main.m


            Dog *dog1 = [Dog new];
            dog1.name = [NSMutableString stringWithString:@"chen"];
            dog1.age = 1;
            NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
            
            //淺復(fù)制
            Dog *dog2 = [dog1 copy];
    //        dog2.name = [NSMutableString stringWithString:@"li"];
            [dog2.name replaceCharactersInRange:NSMakeRange(1, 2) withString:@"hel"];
            dog2.age = 20;
            NSLog(@"dog2.name is %@ and age is %d", dog2.name, dog2.age);
            NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);


2)、運行結(jié)果


    2018-07-15 19:03:35.567556+0800 cyTest[27254:9418105] dog1.name is chen and age is 1
    2018-07-15 19:03:35.567690+0800 cyTest[27254:9418105] dog2.name is cheln and age is 20
    2018-07-15 19:03:35.567768+0800 cyTest[27254:9418105] dog1.name is cheln and age is 1

 
3)、深復(fù)制Demo


Dog.h文件一樣

Dog.m文件有點變化

    #import <Foundation/Foundation.h>
    #import "Dog.h"
     
    @implementation Dog
    @synthesize name;
    @synthesize age;
    -(id)copyWithZone:(NSZone *)zone
    {
        Dog *dog = [[[self class] allocWithZone:zone] init];
    //    dog.name = self.name;
        dog.name =  [self.name mutableCopy];
        dog.age = self.age;
        return dog;
    }
    @end

 
main.m文件一樣


            Dog *dog1 = [Dog new];
            dog1.name = [NSMutableString stringWithString:@"chen"];
            dog1.age = 1;
            NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
            
            //深復(fù)制
            Dog *dog2 = [dog1 copy];
    //        dog2.name = [NSMutableString stringWithString:@"li"];
            [dog2.name replaceCharactersInRange:NSMakeRange(1, 2) withString:@"hel"];
            dog2.age = 20;
            NSLog(@"dog2.name is %@ and age is %d", dog2.name, dog2.age);
            NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);

 
4)、運行結(jié)果


    2018-07-15 19:13:08.751335+0800 cyTest[27529:9427019] dog1.name is chen and age is 1
    2018-07-15 19:13:08.751686+0800 cyTest[27529:9427019] dog2.name is cheln and age is 20
    2018-07-15 19:13:08.751885+0800 cyTest[27529:9427019] dog1.name is chen and age is 1

4、setter方法的復(fù)制選項

我們setter方法復(fù)制選項的時候,如果加了copy屬性,比如setName方法

    -(void)setName : (NSMutableStrinfg *)name
    {
     
        self.name  = [name copy];
     
    }

    #import <Foundation/Foundation.h>
    #import "Dog.h"
     
    @implementation Dog
    @synthesize name;
    @synthesize age;
    @end


所以當(dāng)對象設(shè)置了name屬性的話,就不能再改變了,如下demo


Dog.h

    #import <Foundation/Foundation.h>
    #ifndef Dog_h
    #define Dog_h
     
    @interface Dog : NSObject
    @property (nonatomic, copy) NSMutableString *name;
    @property (nonatomic, assign) int age;
    @end
    #endif /* Dog_h */


Dog.m


    #import <Foundation/Foundation.h>
    #import "Dog.h"
     
    @implementation Dog
    @synthesize name;
    @synthesize age;
    @end


main.m

 

            Dog *dog1 = [Dog new];
            dog1.name = [NSMutableString stringWithString:@"chen"];
            dog1.age = 1;
            [dog1.name appendString:@"hello"];


運行結(jié)果

    2018-07-15 19:22:17.736557+0800 cyTest[27853:9436238] -[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa0000006e6568634
    2018-07-15 19:22:17.739655+0800 cyTest[27853:9436238] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa0000006e6568634'
    *** First throw call stack:
    (
        0   CoreFoundation                      0x0000000104fd61e6 __exceptionPreprocess + 294
        1   libobjc.A.dylib                     0x000000010466b031 objc_exception_throw + 48
        2   CoreFoundation                      0x0000000105057784 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
        3   CoreFoundation                      0x0000000104f58898 ___forwarding___ + 1432
        4   CoreFoundation                      0x0000000104f58278 _CF_forwarding_prep_0 + 120
        5   cyTest                              0x0000000103d60438 main + 600
        6   libdyld.dylib                       0x0000000108a2f955 start + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    (lldb)

很明顯,報錯了。

 



 


作者:chen.yu
深信服三年半工作經(jīng)驗,目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號:編程入門到禿頭 或掃描下面二維碼
零基礎(chǔ)入門進(jìn)階人工智能(鏈接)