ios - 当对象存在时获取 EXC_BAD_ACCESS

标签 ios swift

我正在开发一个带有标准钢琴卷帘类型用户界面的音乐音序器。 它运行良好,直到我在模型方面做了一些更改,但它突然开始在(看似)不相关的部分报告 EXC_BAD_ACCESS。

奇怪的是所有必要的变量都有正确的值,实际上我可以用 po 打印值。 根据我的理解,当对象不存在时就会发生 EXC_BAD_ACCESS,所以这看起来很奇怪。

我的问题是:

  • 即使值存在,EXC_BAD_ACCESS 是否也存在这种情况?
  • 如果是这种情况,可能是什么情况导致的?

任何建议都有帮助。谢谢

[以下是代码]

在我的 UICollectionViewLayout 子类中:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

    // note cells
    let cv = self.collectionView as! YMPianoRollCollectionView;
    let pianoRoll = cv.pianoRollViewController;

    // Call the below func to get the indexes of the Note Objects included in the specified rect
    let indexArray: Array<Int> = pianoRoll!.getNoteIndexes(inRect:rect, useOnlyStartTime: false);

    var retArray : [UICollectionViewLayoutAttributes] = []

    for i in indexArray {
        if let _ = pianoRoll?.pattern.eventSequence[i] as? YMPatternEventNoteOn {
            retArray.append( self.layoutAttributesForPatternEventInfo(i) )
        }
    }        
    return retArray
}

在我的“钢琴卷帘”类中,其中包含 UICollectionView

func getNoteIndexes(inRect rect:CGRect, useOnlyStartTime: Bool) -> Array<Int>  {
    //
    // Transform given values into musical values
    //
    let musicRange :YMMusicalValueRange = screenInfo.getMusicalRange(rect);        
    let startTime = musicRange.origin.time;
    let endTime = musicRange.origin.time + musicRange.size.timeLength;        
    let lowNoteU = musicRange.origin.noteNumber;
    let highNoteU = musicRange.origin.noteNumber + musicRange.size.numberOfNotes;

    var retArray : [Int] = []
    for i in 0..<pattern.eventSequence.count {
        if let e = pattern.eventSequence[i] as? YMPatternEventNoteOn {
            //
            // Prepare ranges
            //
            let noteNo = e.noteNo; //<- App Crashes Here with BAD_ACCESS
            let noteStTime = e.time;
            let noteEnTime = e.time + e.duration;

            let targetNoteRange = Range<Int>(uncheckedBounds: (lowNoteU, highNoteU));

            let targetTimeRange = Range<Int64>(uncheckedBounds: (startTime, endTime))
            let noteTimeRange = Range<Int64>(uncheckedBounds: (noteStTime, noteEnTime))

            //
            // Check the match
            //
            let noteMatches = targetNoteRange.contains(noteNo);
            let timeMatches = useOnlyStartTime ? targetTimeRange.contains(noteStTime)
                                               : targetTimeRange.overlaps(noteTimeRange)
            if noteMatches && timeMatches {
                retArray.append( i );
                NSLog("XXX Found: note \(noteNo) at \(e.time)");
            }
        }
    }
    return retArray;
}

错误:- 对象崩溃时的状态

enter image description here

编辑

这是 YMPatternEventNoteOn 声明

class YMPatternEvent : Codable, CustomDebugStringConvertible {
  var time : YMSequenceTime = 0
  // Some utility funcs follow
  // ...
}

class YMPatternEventNoteOn : YMPatternEvent {
  var noteNo : Int = 64
  var velocity : Int = 127
  var duration : YMSequenceTime = 480

  var tempBendId : Int = 0;
  var tempVibratoId : Int = 0;
  var tempArpeggioId : Int = 0;

  convenience init(time :YMSequenceTime, noteNo : Int, velocity: Int, duration: YMSequenceTime) {
    self.init();
    self.time = time;
    self.noteNo = noteNo;
    self.velocity = velocity;
    self.duration = duration;
  }
  // Other methods follow
  // ...

}

编辑2

注意事件是由用户的操作创建的

//
// In YMPattern object
//
func insertNote(time:YMSequenceTime, noteNo:Int, velocity:Int, duration:YMSequenceTime) -> Int
{
    let onEvent = YMPatternEventNoteOn(time: time, noteNo: noteNo, velocity: velocity, duration: duration);
    let retIndex = insertEvent(onEvent);

    return retIndex;
}

func insertEvent(_ event: YMPatternEvent) -> Int {
    let atTime = event.time;

    var retIndex : Int = 0;
    if(eventSequence.count<1){
        // If it's the first event just add it
        eventSequence.append(event);
        retIndex = 0;
    } else {
        // If any event already exists, insert with time order in consideration
        var i : Int = 0;
        while( atTime > eventSequence[i].time ){
            i += 1;
            if( i >= eventSequence.count ){
                break;
            }
        }
        retIndex = i;
        eventSequence.insert(event, at: i)
    }
 }

//
// In pianoroll view controller
//
func actionButtonReleased(afterDragging: Bool) {
    let values:YMMusicalValuePoint = screenInfo.getMusicalPosition(cursorPosition);        

    // insert new event with default velocity and duration
    let _ = pattern.insertNote(time: values.time, noteNo: values.noteNumber, velocity: 127, duration: screenInfo.timeTicsPerDivision());

    collectionView.reloadData();
}

最佳答案

我已经用某种方法解决了这个问题。

通过将优化级别设置为“整个模块优化”,它停止报告错误。

我不知道内部发生了什么,但如果有人遇到同样的问题,这可能是一个快速解决方案。

关于ios - 当对象存在时获取 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45646141/

相关文章:

ios - 多点触控跟踪问题

ios - UIImageView 上的宽度和高度 NSLayoutConstraints 不起作用

swift - 在不提供 NSTextContainer 的情况下初始化 NSTextView 的子类

ios - 使用基于属性的一组过滤子元素获取核心数据实体

ios - 更新 tableview 后不起作用。为什么会这样?

json - Alamofire检查返回的数据

swift - 下拉菜单标题与条形按钮重叠 - Swift

swift - Facebook 图形 API : Swift SDK not working: GraphRequest

ios - 意外的 SafariViewController react

ios - 如何让我的两个音频播放器同时播放两首不同的歌曲?