Could not cast value of type NSConcreteAttributedString to NSMutableAttributedString

Hi


Since I upgraded to ios13 i have a problem running this piece of code


let text = cell.statusTitleLabel.attributedText as! NSMutableAttributedString
        text.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 1, range: NSMakeRange(0, text.length))
        cell.statusTitleLabel.attributedText = text
        cell.isUserInteractionEnabled = false



The line 1 throws the error of cast exception:

Could not cast value of type 'NSConcreteAttributedString' (0x1ec42a250) to 'NSMutableAttributedString' (0x1ec42a2a0).


Until ios12 that code worked without problems. Any idea why this behaviour is changed and how to fix the problem?


Thanks

Accepted Reply

The type of `attributedText` is `NSAttributedString`, not `NSMutableAttributedString`.

`NSMutableAttributedString` is a subclass of `NSAttributedString`, so `attributedText` may return an `NSMutableAttributedString` in a certain condition. But it's an implementation detail, or in other words, just a luck.


Apps should not be programmed depending on a luck.


Until ios12 that code worked without problems.

You are mis-understanding. The code may have seemingly worked in the past, but it was just a luck, a big problem.


Any idea why this behaviour is changed

Implementation details would change at any time without notifications. Even a 0.0.0 security patch may change such behaviors.


how to fix the problem?

To get a mutable equivalent of an `NSAttributedString`, you use `mutableCopy()`.

        let text = cell.statusTitleLabel.attributedText!.mutableCopy() as! NSMutableAttributedString

(You may want to avoid forced-something like `!` or `as!`, but that's another issue.)

Replies

The type of `attributedText` is `NSAttributedString`, not `NSMutableAttributedString`.

`NSMutableAttributedString` is a subclass of `NSAttributedString`, so `attributedText` may return an `NSMutableAttributedString` in a certain condition. But it's an implementation detail, or in other words, just a luck.


Apps should not be programmed depending on a luck.


Until ios12 that code worked without problems.

You are mis-understanding. The code may have seemingly worked in the past, but it was just a luck, a big problem.


Any idea why this behaviour is changed

Implementation details would change at any time without notifications. Even a 0.0.0 security patch may change such behaviors.


how to fix the problem?

To get a mutable equivalent of an `NSAttributedString`, you use `mutableCopy()`.

        let text = cell.statusTitleLabel.attributedText!.mutableCopy() as! NSMutableAttributedString

(You may want to avoid forced-something like `!` or `as!`, but that's another issue.)

Thanks a lot for your help, I've understood the difference you explained to me 🙂