为什么 NSMutableString 属性的 getter 和 setter 没有出现异常
我刚刚提出了一个错误的答案(已删除)
该代码是为了回答这个问题。 OP 想知道为什么他们得到了 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“尝试使用 setString 改变不可变对象:
(我的回答是一场灾难,因为我没有注意自己在做什么,很累,但仍在学习)通常的借口。:-) )
当他们尝试使用以下内容设置可变字符串时:
[firstName setString:@""];
该属性是 NSMutableString
@property (copy,nonatomic) NSMutableString* firstName
我发布了一些对我有用的代码。但将 getter 误认为是 setter。 (我还是新人,而且很累:-))
现在令人困惑的是,一旦有人指出我错了。我重新查看了我的代码并意识到我做了什么。
但在我的项目中,我只合成了 setter 而没有声明。
@synthesize firstName =_firstName;
我已经像这样声明了 getter:
-(NSMutableString *)firstName{
if (!_firstName) _firstName = [[NSMutableString alloc]init];
return _firstName;
}
但是如果我没有声明 setter,一切都可以正常工作。您应该对可变对象的属性执行哪些操作,并且(复制)
如果放入设置器:
-(void)setFirstName:(NSMutableString *)mutableString{
_firstName = mutableString ;
}
它仍然可以正常工作。 我使用这个调用:
[self.firstName setString:@"some words"];
当我认为我第一次删除了 getter 并留下了 setter 时,我确实得到了异常。 但我不能重复这个错误!
我希望这一点很清楚..
有谁知道发生了什么事。在这种情况下,我是否正确地执行了 setter 和 getter?
谢谢
I just put up a wrong answer (deleted)
The code was in response to this question. The OP wanted to know why they got a
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with setString:
(My answer was a calamity of me not paying attention to what I was doing, being tired and still learning. The usual excuses. :-) )
When they tried to set the mutable string with:
[firstName setString:@""];
The property is a NSMutableString
@property (copy,nonatomic) NSMutableString* firstName
I posted a bit of code that was working for me. But mistook the getter for the setter.
(I am still new, and tired :-) )
Now what is confusing is once it was pointed out that I was wrong. I re-looked at my code and realised what I had done.
But in my project I only had the setter synthesised and not declared.
@synthesize firstName =_firstName;
And I had declared the getter like so:
-(NSMutableString *)firstName{
if (!_firstName) _firstName = [[NSMutableString alloc]init];
return _firstName;
}
But all was working with no issue without me declaring a setter. Which your supposed to do for a property for a mutable object and (copy)
If put a setter in :
-(void)setFirstName:(NSMutableString *)mutableString{
_firstName = mutableString ;
}
It still works all ok.
I use the call:
[self.firstName setString:@"some words"];
I did get the Exception once when I think I first removed the getter and leaving the setter.
But I cannot repeat the error!
I hope this is clear..
Does any one know what is going on. And am I doing the setter and getter correctly in this case.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您编写的设置器不正确,因为它没有创建传入字符串的可变副本。
但我认为您真正的问题是为什么您在这里没有看到异常。原因是:您在此处发布的代码中实际上并未使用错误的设置器。
这是您发布的代码:
[self.firstName setString:@"some Words"];
这基本上与此相同:
所以首先您使用 getter,它会正确返回 NSMutableString*。然后调用 Foundation 中已定义的方法 -[NSMutableString setString:]。这工作正常,因为您实际上将其发送到 NSMutableString。到目前为止,您已经避免了任何问题。
你可能会遇到这样的异常:
我希望这会有所帮助。
顺便说一句,听起来你正在使用 ARC。在这种情况下,正确的设置器可以像这样简单:
The setter you wrote is incorrect for the reason that it doesn't make a mutable copy of the string which is passed in.
But I think your real question is why you don't see an exception here. The reason is: you haven't actually used the bad setter in the code you posted here.
Here is the code you posted:
[self.firstName setString:@"some words"];
This is basically the same as this:
So first you use your getter, which correctly returns an NSMutableString*. Then you call a method that is already defined in Foundation called -[NSMutableString setString:]. This works fine because you are in fact sending it to an NSMutableString. So far you have avoided any issue.
Where you would have gotten an exception is something like this:
I hope that helps.
BTW, it sounds like you are using ARC. In that case, a correct setter can be as simple as this:
给定一个属性声明:
在非 ARC 代码中,setter 应该像这样实现:
或像这样:
简单的赋值是不行的,因为如果不复制新值,你就会崩溃。简单的
copy
也不会这样做,因为 ivar 是一个可变字符串。Given a property declaration:
In non-ARC code the setter should be implemented like this:
or like this:
A simple assignment won't do because without copying the new value you will crash. A simple
copy
won't do either because the ivar is a mutable string.