iOS Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to m…

报错:Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to mutate immutable object with appendString:’

先上有问题的代码

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic,copy) NSMutableString *muStr;//最终要输出的字符串
@property (nonatomic,assign) int index;//数组下标
@property (nonatomic,copy) NSArray *sourceArr;//保存数据源
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //数据初始化
    self.view.backgroundColor = [UIColor whiteColor];
    NSString *str = @"Hellon,nWolrdn!";
    self.index = 0;
    self.sourceArr = [str componentsSeparatedByString:@"n"];
    self.muStr = [NSMutableString stringWithString:@""];
    
    //测试按钮
    UIButton *btn = [[UIButton alloc] init];
    [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    [btn setTitle:@"点我啊" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    btn.titleLabel.font = [UIFont systemFontOfSize:15];
    [btn sizeToFit];
    btn.center = self.view.center;
    [self.view addSubview:btn];
}

- (void)btnClick {
    //这里可能会有数组下标越界的问题,不是此次探讨的重点,先忽略
    [self.muStr appendString:self.sourceArr[self.index]];
    NSLog(@"%@",self.muStr);
    self.index = self.index + 1;
}


@end

咋看起来, muStr 明明声明的是全局的可变字符串类型,但是当调用appendString:这个方法时却报了上面那个错。在控制台把类型打印出来却发现,self.muStr 居然是不可变的,如下图所示:

image.png

苹果给的解释是:
The problem is due to the copy attribute on your property. When you assign a value to the property, it creates a copy. But the copy is made with copy and not mutableCopy so you actually end up assigning an NSString to the property and not an NSMutableString.
Get rid of copy on the property or implement your own custom “setter” method that calls mutableCopy.

因此,实际上,这里有两种解决方法:
(1)把上面有问题的代码中出现的self.muStr 全部替换成 _muStr;
(2)重写set方法

- (void)setAddressName:(NSMutableString *)addressName {
    _addressName = [addressName mutableCopy];
}

因为属性没有mutableCopy,所以实际还是copy。

【信息由网络或者个人提供,如有涉及版权请联系COOY资源网邮箱处理】

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容