2016-06-21 14 views
3

カスタムNSTextStorageクラスを定義してAppleのTextKitを利用するカスタムUITextViewがありますが、カスタムテキストビューのテキストストレージ(以下に実装されているように)にサブクラスを使用すると、 20.0KBを超えるファイルを開こうとすると、メモリリークのためにアプリがクラッシュする: "Message from debugger: Terminated due to memory issue"奇妙なことにサブクラスNSTextStorageは重要なメモリの問題を引き起こします

、私はちょうど標準1、NSTextStorage、テキストの任意のメモリリークせずに即座にロードし、RAMの< 30メガバイトを使用して、私のカスタムBMTextStorageを交換する場合。これを引き起こしているのは何ですか?

TextView.swift

class TextView : UITextView { 

    required init(frame: CGRect) { 

     // If I replace the following line with simply 
     // "let textStorage = NSTextStorage()" 
     // I can open any file of any size and not have a memory leak 
     // issue, using only about 20-30MB of RAM. If I ran this code 
     // as is, it can open most files less than 20KB but will 
     // crash otherwise. 
     let textStorage = BMTextStorage() 

     let layoutManager = NSLayoutManager() 

     layoutManager.allowsNonContiguousLayout = true 

     let textContainer = NSTextContainer(size: CGSizeMake(.max, .max)) 

     textContainer.widthTracksTextView = true 
     textContainer.heightTracksTextView = true 
     textContainer.exclusionPaths = [UIBezierPath(rect: CGRectMake(0.0, 0.0, 40.0, .max))] 

     layoutManager.addTextContainer(textContainer) 
     textStorage.addLayoutManager(layoutManager) 

     super.init(frame: frame, textContainer: textContainer) 

     textStorage.delegate = self 
     layoutManager.delegate = self 

    } 

} 

BMTextStorage.swift

typealias PropertyList = [String : AnyObject] 

class BMTextStorage : NSTextStorage { 

    override var string: String { 
     return storage.string 
    } 

    private var storage = NSMutableAttributedString() 

    override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> PropertyList { 
     return storage.attributesAtIndex(location, effectiveRange: range) 
    } 

    override func replaceCharactersInRange(range: NSRange, withString str: String) { 
     storage.replaceCharactersInRange(range, withString: str) 
     edited([.EditedAttributes, .EditedCharacters], range: range, changeInLength: str.length - range.length) 
    } 

    override func setAttributes(attrs: PropertyList?, range: NSRange) { 
     storage.setAttributes(attrs, range: range) 
     edited([.EditedAttributes], range: range, changeInLength: 0) 
    } 

    override func processEditing() { 
     super.processEditing() 
    } 

} 
+0

上書きする4つの方法のいずれかに絞り込むことはできますか? (そして 'processEditing()'は何もしないので、完全に削除することができます。) – NRitH

+0

@NRitH抽象クラスによってオーバーライドされるために必要なメソッドであるため、簡単に絞り込むことはできません。はい、私は 'processEditing()'を省略しても問題は変わりません。私が想定したブレークポイントを試しましたが、大きなファイルの場合特にクラッシュする前に永遠にループします。 –

答えて

3

うわー....私はNSTextStoragestorageの種類を変更したときに、それが固定しまった、奇妙な... 。

typealias PropertyList = [String : AnyObject] 

class BMTextStorage : NSTextStorage { 

    overrride var string: String { 
     return storage.string 
    } 

    private var storage = NSTextStorage() 

    override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> PropertyList { 
     return storage.attributesAtIndex(location, effectiveRange: range) 
    } 

    override func replaceCharactersInRange(range: NSRange, withString str: String) { 
     storage.replaceCharactersInRange(range, withString: str) 
     edited([.EditedAttributes, .EditedCharacters], range: range, changeInLength: str.length - range.length) 
    } 

    override func setAttributes(attrs: PropertyList?, range: NSRange) { 
     storage.setAttributes(attrs, range: range) 
     edited([.EditedAttributes], range: range, changeInLength: 0) 
    } 

    override func processEditing() { 
     super.processEditing() 
    } 

} 
+1

Genius move!しかし、これがどのような奇妙なケースが崩壊するのだろうかと思う。そして 'self'と' storage'の両方に対して 'beginEditing' /' endEditing'を呼び出さなければなりませんか?しかし、今のところ記憶上の問題は残っています。 – ctietze

+1

@ctietze奇妙なことに、私は 'self'の' beginEditing'と 'endEditing'呼び出しを行い、うまく動作します。私はこれらのメソッドが主にアプリケーションのドキュメント状態を管理するのに役立つと信じています –

+0

これはAppleのAPIからの大量のコード臭いのように感じられますが.../heck/NSTextStorageがなぜ抽象クラスであるのかObjective-Cで意味をなさないものは、この強力なクラスの背後に黒い魔法があることを示す大きな兆候です。しかし、チップをありがとう! +1 –

関連する問題