NSString NSMutableString NSArray NSMutableArray Block 分别用哪些修饰?

NSString

@property (nonatomic , strong) NSString * strongString;
@property (nonatomic , copy) NSString * mCopyString;
       NSMutableString * tempStr = [[NSMutableString alloc] init];
    [tempStr appendFormat:@"test"];
    self.strongString = tempStr;
    self.mCopyString = tempStr;
    NSLog(@"strongString %p %@",self.strongString,self.strongString);
    NSLog(@"mCopyString %p %@",self.mCopyString,self.mCopyString);
    [tempStr appendFormat:@"change"];
    NSLog(@"strongString %p %@",self.strongString,self.strongString);
    NSLog(@"mCopyString %p %@",self.mCopyString,self.mCopyString);

以下是打印结果

2017-11-19 16:52:30.307674+0800 test[4346:378408] strongString 0x600000256b60 test
2017-11-19 16:52:30.307840+0800 test[4346:378408] mCopyString 0xa000000747365744 test
2017-11-19 16:52:30.307943+0800 test[4346:378408] strongString 0x600000256b60 testchange
2017-11-19 16:52:30.308060+0800 test[4346:378408] mCopyString 0xa000000747365744 test

结论: NSString 是不可变字符串,修饰的时候应该用 copy 修饰,这样它的值不会发生改变

NSMutableString

//如果这样修饰会出现什么问题呢?
@property (nonatomic , copy) NSMutableString * mCopyString;
    self.mCopyString = [[NSMutableString alloc] init];
    [self.mCopyString appendFormat:@"test"];

会这样报错

2017-11-19 16:58:24.268556+0800 test[4403:382549] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendFormat:'
*** First throw call stack:

借着这个例子我们说下 copy

copy:建立一个引用计数为1的对象,然后释放原有对象;常常用于NSString/NSArray/NSDictionary(不可变)。在赋值时传入值的一份拷贝,拷贝工作由copy方法执行
其实这里给 NSString 进行赋值的对象是 NSString 那就和 strong 是一样的,如下:

@property (nonatomic , copy) NSString * mCopyString;
    NSString * tempStr = @"test";
    NSLog(@"%p %@",tempStr,tempStr);
    self.mCopyString = tempStr;
    NSLog(@"%p %@",self.mCopyString,self.mCopyString);
2017-11-19 17:10:12.655578+0800 test[4507:390294] 0x1016d4098 test
2017-11-19 17:10:12.655740+0800 test[4507:390294] 0x1016d4098 test

如果是可变的,就会 copy 一份

@property (nonatomic , copy) NSString * mCopyString;
    NSMutableString * tempStr = [[NSMutableString alloc] init];
    [tempStr appendFormat:@"test"];
    NSLog(@"%p %@",tempStr,tempStr);
    self.mCopyString = tempStr;
    NSLog(@"%p %@",self.mCopyString,self.mCopyString);
2017-11-19 17:07:55.904637+0800 test[4490:388984] 0x60400045c7d0 test
2017-11-19 17:07:55.904808+0800 test[4490:388984] 0xa000000747365744 test

NSArray

@property (nonatomic , copy) NSArray * mCopyArray;
@property (nonatomic , strong) NSArray * mStrongArray;
    NSArray * mArray = @[@"1",@"2"];
    NSLog(@"mArray %p %@",mArray,mArray);
    self.mCopyArray = mArray;
    NSLog(@"self.mCopyArray %p %@",self.mCopyArray,self.mCopyArray);

    NSMutableArray * mMutableArray = [[NSMutableArray alloc] init];
    [mMutableArray insertObject:@"1" atIndex:0];
    NSLog(@"mMutableArray %p %@",mMutableArray,mMutableArray);
    self.mCopyArray = mMutableArray;
    NSLog(@"self.mCopyArray %p %@",self.mCopyArray,self.mCopyArray);
    [mMutableArray insertObject:@"2" atIndex:0];
    NSLog(@"self.mCopyArray %p %@",self.mCopyArray,self.mCopyArray);

    NSMutableArray * mStrongArray = [[NSMutableArray alloc] init];
    [mStrongArray insertObject:@"1" atIndex:0];
    NSLog(@"mStrongArray %p %@",mStrongArray,mStrongArray);
    self.mStrongArray = mStrongArray;
    NSLog(@"self.mStrongArray %p %@",self.mStrongArray,self.mStrongArray);
    [mStrongArray insertObject:@"2" atIndex:0];
    NSLog(@"self.mStrongArray %p %@",self.mStrongArray,self.mStrongArray);

打印结果

2017-11-19 17:19:04.207782+0800 test[4664:398783] mArray 0x60400003a720 (
    1,
    2
)
2017-11-19 17:19:04.208416+0800 test[4664:398783] self.mCopyArray 0x60400003a720 (
    1,
    2
)
2017-11-19 17:19:04.208703+0800 test[4664:398783] mMutableArray 0x604000252a50 (
    1
)
2017-11-19 17:19:04.210955+0800 test[4664:398783] self.mCopyArray 0x604000009650 (
    1
)
2017-11-19 17:19:04.211328+0800 test[4664:398783] self.mCopyArray 0x604000009650 (
    1
)
2017-11-19 17:19:04.211413+0800 test[4664:398783] mStrongArray 0x604000252bd0 (
    1
)
2017-11-19 17:19:04.211483+0800 test[4664:398783] self.mStrongArray 0x604000252bd0 (
    1
)
2017-11-19 17:19:04.211551+0800 test[4664:398783] self.mStrongArray 0x604000252bd0 (
    2,
    1
)

结论: NSArray 使用 copy 修饰时,如果赋值对象是不可变数组,那么相当于直接 retain , 如果是 可变数组 , 那么会 copy 一份并且 retain
但是 NSArray 如果使用 strong 赋值,那么,可能会出现一些 bug: 如果赋值对象是可变数组, 可变数组改变了值, NSArray 也会一样改变

NSMutableArray

@property (nonatomic , copy) NSMutableArray * mMutableArray;
    self.mMutableArray = [[NSMutableArray alloc] init];
    [self.mMutableArray insertObject:@"1" atIndex:0];
2017-11-19 17:23:45.441256+0800 test[4682:401433] -[__NSArray0 insertObject:atIndex:]: unrecognized selector sent to instance 0x600000007e80
(lldb) 

结论: NSMutableArray 需要使用 strong 修饰

NSDictionary

同理 NSArray

@property (nonatomic , copy) NSDictionary * mCopyDictionary;
@property (nonatomic , strong) NSDictionary * mStrongDictionary;
    NSDictionary * mDict = @{@"xiaoli":@"123"};
    NSLog(@"mDict %p %@",mDict,mDict);
    self.mCopyDictionary = mDict;
    NSLog(@"self.mCopyDictionary %p %@",self.mCopyDictionary,self.mCopyDictionary);

    NSMutableDictionary * mMutableDict = [[NSMutableDictionary alloc] init];
    [mMutableDict setObject:@"456" forKey:@"xiaowang"];
    NSLog(@"mMutableArray %p %@",mMutableDict,mMutableDict);
    self.mCopyDictionary = mMutableDict;
    NSLog(@"self.mCopyArray %p %@",self.mCopyDictionary,self.mCopyDictionary);
    [mMutableDict setObject:@"789" forKey:@"xiaoming"];
    NSLog(@"self.mCopyArray %p %@",self.mCopyDictionary,self.mCopyDictionary);


    NSMutableDictionary * mStrongDict = [[NSMutableDictionary alloc] init];
    [mStrongDict setObject:@"xiaoli" forKey:@"125"];
    NSLog(@"mStrongArray %p %@",mStrongDict,mStrongDict);
    self.mStrongDictionary = mStrongDict;
    NSLog(@"self.mStrongArray %p %@",self.mStrongDictionary,self.mStrongDictionary);
    [mStrongDict setObject:@"xiaoli" forKey:@"999"];
    NSLog(@"self.mStrongArray %p %@",self.mStrongDictionary,self.mStrongDictionary);
2017-11-19 17:32:04.841820+0800 test[4728:406099] mDict 0x60000003eda0 {
    xiaoli = 123;
}
2017-11-19 17:32:04.842005+0800 test[4728:406099] self.mCopyDictionary 0x60000003eda0 {
    xiaoli = 123;
}
2017-11-19 17:32:04.842179+0800 test[4728:406099] mMutableArray 0x60400003dd80 {
    xiaowang = 456;
}
2017-11-19 17:32:04.842351+0800 test[4728:406099] self.mCopyArray 0x604000230e00 {
    xiaowang = 456;
}
2017-11-19 17:32:04.842500+0800 test[4728:406099] self.mCopyArray 0x604000230e00 {
    xiaowang = 456;
}
2017-11-19 17:32:04.842631+0800 test[4728:406099] mStrongArray 0x60000003efe0 {
    125 = xiaoli;
}
2017-11-19 17:32:04.842737+0800 test[4728:406099] self.mStrongArray 0x60000003efe0 {
    125 = xiaoli;
}
2017-11-19 17:32:04.842842+0800 test[4728:406099] self.mStrongArray 0x60000003efe0 {
    125 = xiaoli;
    999 = xiaoli;
}

结论: NSDictronary 用 copy 修饰

NSMutableDictronary

@property (nonatomic , copy) NSMutableDictionary * mMutableDict;
    self.mMutableDict = [[NSMutableDictionary alloc] init];
    [self.mMutableDict setObject:@"xiaoli" forKey:@"123"];
2017-11-19 17:34:57.436056+0800 test[4746:407822] -[__NSFrozenDictionaryM setObject:forKey:]: unrecognized selector sent to instance 0x60000003a980
(lldb) 

结论: NSMutableDictionary 用 strong 修饰

Block

分析下面代码有无实现ip为2001::1的逻辑 // // SDNV6LanDhcpHelper.m // Omada // // Created by zzp on 2025/7/11. // Copyright © 2025 TP-Link. All rights reserved. // #import "SDNV6LanDhcpHelper.h" #import "TPSDNControllerCommonMethod.h" #import "TPIPv6Calculator.h" @implementation SDNV6LanDhcpHelper - (void)updateWithGateway:(NSString *)gateway andCount:(NSString *)count { NSArray<NSString *> *iparr = [gateway componentsSeparatedByString:@"."]; NSMutableString *ipstr = [[NSMutableString alloc]init]; for (int i = 0; i<4; i++) { [ipstr appendString:[TPSDNControllerCommonMethod toBinarySystemWithDecimalSystem:iparr[i]]]; } NSString *ipmin = [ipstr copy]; NSString *ipmax = [ipstr copy]; NSString *subnetMask = [ipstr copy]; for (int i = [count intValue]; i<ipmin.length; i++) { ipmin = [ipmin stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:@"0"]; } for (int i = [count intValue]; i<ipmax.length; i++) { ipmax = [ipmax stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:@"1"]; } for (int i = 0; i<[count intValue]; i++) { subnetMask = [subnetMask stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:@"1"]; } for (int i = [count intValue]; i<ipmax.length; i++) { subnetMask = [subnetMask stringByReplacingCharactersInRange:NSMakeRange(i, 1) withString:@"0"]; } NSString *ipminrange = [ipmin stringByReplacingCharactersInRange:NSMakeRange(ipmin.length-1, 1) withString:@"1"]; NSString *ipmaxrange = [ipmax stringByReplacingCharactersInRange:NSMakeRange(ipmax.length-1, 1) withString:@"0"]; NSMutableArray<NSString *> *broadCastList = [[NSMutableArray alloc]init]; NSMutableArray<NSString *> *iparrmin = [[NSMutableArray alloc]init]; NSMutableArray<NSString *> *iparrmax = [[NSMutableArray alloc]init]; NSMutableArray<NSString *> *subnetMaskList = [[NSMutableArray alloc]init]; NSString *broadCast = [NSString new]; NSString *rangeLeft = [[NSString alloc]init]; NSString *rangeRight = [[NSString alloc]init]; NSString *subnet = [[NSString alloc]init]; for (int i = 0; i<4; i++) { [iparrmax addObject:[TPSDNControllerCommonMethod toDecimalSystemWithBinarySystem:[ipmaxrange substringWithRange:NSMakeRange(i*8, 8)]]]; [iparrmin addObject:[TPSDNControllerCommonMethod toDecimalSystemWithBinarySystem:[ipminrange substringWithRange:NSMakeRange(i*8, 8)]]]; [broadCastList addObject:[TPSDNControllerCommonMethod toDecimalSystemWithBinarySystem:[ipmax substringWithRange:NSMakeRange(i*8, 8)]]]; [subnetMaskList addObject:[TPSDNControllerCommonMethod toDecimalSystemWithBinarySystem:[subnetMask substringWithRange:NSMakeRange(i*8, 8)]]]; broadCast = [broadCast stringByAppendingString:[broadCastList objectAtIndex:i]]; rangeLeft = [rangeLeft stringByAppendingString:[iparrmin objectAtIndex:i]]; rangeRight = [rangeRight stringByAppendingString:[iparrmax objectAtIndex:i]]; subnet = [subnet stringByAppendingString:[subnetMaskList objectAtIndex:i]]; if (i<3) { broadCast = [broadCast stringByAppendingString:@"."]; rangeLeft = [rangeLeft stringByAppendingString:@"."]; rangeRight = [rangeRight stringByAppendingString:@"."]; subnet = [subnet stringByAppendingString:@"."]; } } double Ipv4Count =pow(2, 32-[count intValue])-2; self.gateway = gateway; self.broadCast = broadCast; self.count = [NSString stringWithFormat:@"%0.f",Ipv4Count]; self.range = [NSString stringWithFormat:@"%@ - %@",rangeLeft,rangeRight]; self.subnetMask = subnet; self.suggestRangeStart = rangeLeft; self.suggestrangeEnd = rangeRight; } - (void)updateWithIpv6Gateway:(NSString *)gateway andCount:(NSString *)count { TPIPv6Calculator *ipv6Calculator = [[TPIPv6Calculator alloc] initWithAddress:gateway prefix:count]; ipv6Calculator.dhcpRangeCount = 2000; self.gateway = ipv6Calculator.gatewayIpv6Str; self.broadCast = ipv6Calculator.ipv6Address; self.count = ipv6Calculator.ipv6Count; self.range = ipv6Calculator.ipv6Range; self.suggestRangeStart = ipv6Calculator.dhcpStartStr; self.suggestrangeEnd = ipv6Calculator.dhcpEndStr; } @end
最新发布
12-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值