는 내가 가진 모든 다른 BAD_ACCESS 전에 일반적으로 빠른 오타 수정했다, 그러나 이것은 매우 혼란팬텀 EXC_BAD_ACCESS
이 코드는 있다고하는 .ics 인 구글 캘린더 파일을 다운로드 한 후 파서 함수에 전달할 예정이다(하지 여기에 포함 된) 이벤트 객체의 배열을 반환합니다
물리적 iOS 장비에서 테스트 할 때이 라인이
를 호출 할 때 문제는, loadEventIntoCalendar()의 모든 3 - 4 실행가 EXC_BAD_ACCESS가 발생한다tempHold = calendarString.substring(with: tempRange)
은 event() 함수의 while 루프에 있습니다.
많은 다른 기술로이 문제를 해결하려고했습니다. 좀비 오브젝트가 똑바로 나오면 로그에 아무것도 인쇄되지 않습니다. 인스트루먼트으로 실행 분석을 시도했지만 유용하지 않은 항목을 찾지 못했습니다. 인수에 전달 된 String 파일의 별도 복사본을 만들려고했으나 아무 것도 변경하지 않았습니다.
나는이 문제가 calendarString과 관련이 있거나 적어도 가리키는 값과 관련이 있다고 확신한다. Xcode를 통해 메모리 블록을 분석해 보았습니다. 그러나 오류를 일으키는 메모리 위치를 가리키는 변수를 찾을 수 없었습니다.
나는 단지 싱글 정적 기능이 있어야하는데
이벤트() ( 계기와 검사) 약 70 메가 바이트 최대를 차지 RAM 전체 응용 프로그램으로 과부하가되지 않을 것이라고 확신 해요. 여기
이 상대적으로 빨리 완료 할 수있는 두 가지 기능func loadEventsIntoCalendar() {
// The link from which the calendar is downloaded
let url = URL (string: "https://calendar.google.com/calendar/ical/wlmacci%40gmail.com/public/basic.ics")!
// The process of downloading and parsing the calendar
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
// The following is simply a declaration and will not execute without the line 'task.resume()'
if let URLContent = data { // If Data has been loaded
// If you got to this point then you've downloaded the calendar so...
// Calendar File parsing starts here!!!
// The string that holds the contents of the calendar's events
var webContent:String = String(data: URLContent, encoding:String.Encoding.utf8)!
self.events(forCalendarFile: &webContent, inCalendar: Calendar(identifier: Calendar.Identifier.gregorian))
}
})
task.resume()
}
// Calendar Parser for this VC
func events(forCalendarFile webContent:inout String, inCalendar calendar:Calendar) {
// The reason for this complication is, i thought copying the object might solve the issue, it did not :(
let NSWebContent = NSString(string: webContent)
let calendarString = NSWebContent.copy() as! NSString
// An array of flags used for locating the event fields
// [h][0] - The flag that marks the begining of a field, [h][1] - The flag that marks the end of a field
let searchTitles:[[String]] = [["SUMMARY:", "TRANSP:"], ["DESCRIPTION:", "LAST-MODIFIED:"], ["DTSTART", "DTEND"], ["DTEND", "DTSTAMP"], ["LOCATION:", "SEQUENCE:"]]
// The range of "webContent's" content that is to be scanned
// Must be decreased after each event is scanned
var range:NSRange = NSMakeRange(0, calendarString.length - 1)
// Inside function that will be used to determine the 'difference' range between the begining and end flag ranges.
let findDifference:(NSRange, NSRange) -> NSRange = {(first:NSRange, second:NSRange) -> NSRange in
let location = first.location + first.length, length = second.location - location // Determine the start position and length of our new range
return NSMakeRange(location, length) // Create and return the new range
}
// Inside function that will be used to move the searching range to the next event
// Returns an NSNotFound range (NSNotFound, 0) if there are no more events
let updateRange:(NSRange) -> NSRange = {(oldRange:NSRange) -> NSRange in
let beginingDeclaration = calendarString.range(of: "BEGIN:VEVENT", options: NSString.CompareOptions.literal, range: oldRange)
// If the "BEGIN:VEVENT" was not found in webContent (no more events)
if NSEqualRanges(beginingDeclaration, NSMakeRange(NSNotFound, 0)) {
return beginingDeclaration // Return an 'NSNotFound' range (Named it myself;)
}
// Calculate the index of the last character of 'beginingDeclaration' flag
let endOfBeginingDeclaration = beginingDeclaration.location + beginingDeclaration.length
// Calculate the length of the new range
let length = oldRange.length - endOfBeginingDeclaration + oldRange.location
// Calculate the starting location of the new range
let location = endOfBeginingDeclaration
// Create and return the new range
return NSMakeRange(location, length)
}
// A holder for the begining and end flags for each event field
var fieldBoundaries:[NSRange]
// The actual parsing of each event
repeat {
range = updateRange(range) // Move our searching range to the next event
if NSEqualRanges(range, NSMakeRange(NSNotFound, 0)) { // If there are no more events in the searching range
break; // Then no more shall be added (break from the loop)
}
var tempHold:String!
// Record each field into our event database
for h in 0...searchTitles.count-1 {
fieldBoundaries = [NSRange]() // Clear the fieldBoundaries for the new search
fieldBoundaries.append(calendarString.range(of: searchTitles[h][0], options: NSString.CompareOptions.literal, range: range)) // Find the begining flag
fieldBoundaries.append(calendarString.range(of: searchTitles[h][1], options: NSString.CompareOptions.literal, range: range)) // Find the ending flag
let tempRange = findDifference(fieldBoundaries[0], fieldBoundaries[1])
print ("Isolating event content")
tempHold = calendarString.substring(with: tempRange) // Create a new string from whatever is in between the two flags. This will be the current field of the event
print ("Event content isolated")
tempHold = tempHold.trimmingCharacters(in: CharacterSet.newlines) // Remove all /r /n and other 'new line' characters from the event field
tempHold = tempHold.replacingOccurrences(of: "\u{005C}", with: "", options: .literal, range: nil) // Replace all backslashes from the event field
}
} while (true)
}
, 그래서 빠른 응답이 크게 이해할 수있을 것이다.
미리 감사드립니다.
'tempHold = calendarString.substring (with : tempRange)'또는 중단 직전에'tempRange' 및'calendarString'을 로깅 해 본 적이 있습니까? –
문제는 메모리 내부의 구성 요소 중 일부가 실행 과정 중 절반 이상이 손상 되었기 때문에 중단 점이 한 지점에서 완전히 활성 변수가 있고 다음 지점에서 손상된 부분을 제외하고는 많이 표시하지 않을 것이라는 점입니다. 내가 오류의 원인을 표시하지 않습니다 – sketch204