patternswiftMinor
Removing a subview with a subview from a UIView without memory leaks
Viewed 0 times
subviewwithoutremovingwithuiviewmemoryfromleaks
Problem
I made a custom
The
Whenever the parent
What I am worried about is memory leaks. Since the grandchild view
This demo project can be found on github, but here is the custom class code:
```
import UIKit
@IBDesignable class UIMongolTextView: UIView {
// ** Unique to TextView **
private let view = UITextView()
let mongolFontName = "ChimeeWhiteMirrored"
@IBInspectable var text: String {
get {
if let txt = view.text {
return txt
} else {
return ""
}
}
set {
view.text = newValue
}
}
func setup() {
view.text = self.text
view.backgroundColor = self.backgroundColor
view.font = UIFont(name: mongolFontName, size: 24)
}
// ***
// General code for Mongol views
// ***
private var oldWidth: CGFloat = 0
private var oldHeight: CGFloat = 0
UITextView for vertical Mongolian writing. It is made by subclassing UIView, which has a subview called rotatedView. This rotatedView itself has a UITextView subview. So there are three views: a parent, a child, and a grandchild.The
UITextView contains the actual text. The rotatedView is a container that gives the text the correct vertical orientation and line wrapping. The parent UIView is the container that allows autolayout to work normally in the Interface Builder. For more background, please see here and here.Whenever the parent
UIView frame changes, the old rotatedView is removed and a new instance is made. Then the UITextView (a property of the custom UIView subclass) is added to the rotatedView.What I am worried about is memory leaks. Since the grandchild view
UITextView is a property of my custom view but rotatedView isn't. When I drop rotatedView on a frame size change, is any reference kept to it since the UITextView property is a subview of rotatedView?This demo project can be found on github, but here is the custom class code:
```
import UIKit
@IBDesignable class UIMongolTextView: UIView {
// ** Unique to TextView **
private let view = UITextView()
let mongolFontName = "ChimeeWhiteMirrored"
@IBInspectable var text: String {
get {
if let txt = view.text {
return txt
} else {
return ""
}
}
set {
view.text = newValue
}
}
func setup() {
view.text = self.text
view.backgroundColor = self.backgroundColor
view.font = UIFont(name: mongolFontName, size: 24)
}
// ***
// General code for Mongol views
// ***
private var oldWidth: CGFloat = 0
private var oldHeight: CGFloat = 0
Solution
@IBInspectable var text: String {
get {
if let txt = view.text {
return txt
} else {
return ""
}
}
set {
view.text = newValue
}
}Just a small thing to comment on, however, a couple of notes here.
First, with Xcode 7, which is right around the corner,
UITextView's text property will be a regular String instead of String!, so we can eliminate this if statement altogether.However, in the meantime, this becomes a lot cleaner with the nil-coalescing operator:
get {
return view.text ?? ""
}Another minor comment:
transform = CGAffineTransformScale(transform, CGFloat(-1), CGFloat(1))Using the
CGFloat constructor here is unnecessary. We can just use the literals:transform = CGAffineTransformScale(transform, -1, 1)Code Snippets
@IBInspectable var text: String {
get {
if let txt = view.text {
return txt
} else {
return ""
}
}
set {
view.text = newValue
}
}get {
return view.text ?? ""
}transform = CGAffineTransformScale(transform, CGFloat(-1), CGFloat(1))transform = CGAffineTransformScale(transform, -1, 1)Context
StackExchange Code Review Q#100431, answer score: 4
Revisions (0)
No revisions yet.