当结果为0时,Swift和Realm EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)

时间:2015-01-16 10:36:44

标签: swift objective-c++ realm

我的代码中有一个看起来无害的电话:

let index = allFilms.indexOfObject(film)

它通常没有问题,但是当index的值为0 时,我的应用程序在此行崩溃,也就是说filmallFilms中的第一项},错误为EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

这是对Realm的调用,它在内部使用以下Objective-C ++代码来创建返回值:

- (NSUInteger)indexOfObject:(RLMObject *)object 
  // [...]
  size_t object_ndx = object->_row.get_index();
  size_t result = _backingView.find_by_source_ndx(object_ndx);
  if (result == tightdb::not_found) {
    return NSNotFound;
  }
  return result;
}

有人知道这里发生了什么吗?

为了更清楚地说明,索引不会以NSNotFound的形式返回,它会以0的形式返回。

[编辑]我想知道Swift是否正在做一些聪明的事情,它知道我如何在该方法中进一步投射这个值。这是完整的方法,您可以看到我在UIntInt之间进行投射。

func pageWithOffset(offset:Int, fromFilmWithIdentifier identifier:NSInteger)->UIViewController?{
    let allFilms = Film.objectsWithPredicate(FilmQueries.predicateForCurrentlyAvailable())

    let predicate = NSPredicate(format: "id == \(currentFilmIdentifier)")
    let film = Film.findById(currentFilmIdentifier)

    var index = allFilms.indexOfObject(film)

    if index == UInt(NSNotFound) { return nil }
    let resultIndex = Int(index) + offset;
    if index < 0 || index >= allFilms.count - 1{
        return nil
    }else{
        let film = allFilms[UInt(resultIndex)] as Film
        return pageForFilmWithIdentifier(film.id)
    }
}

2 个答案:

答案 0 :(得分:0)

我认为问题来自indexOfObject返回NSNotFound时。您应该检查index == NSNotFound,如果是,则不要访问该阵列。

答案 1 :(得分:0)

这肯定看起来像一个Realm bug,虽然我无法重现它。你能在Realm中创建一个失败的单元测试来重现这个问题吗?这是我的(失败)尝试,您可以将其用作跳跃点:

func testStackOverflow27982054() {
    let realm = realmWithTestPath()
    realm.transactionWithBlock {
        SwiftStringObject.createInRealm(realm, withObject: ["a"]); return
    }
    let allStrings = SwiftStringObject.objectsInRealm(realm, "stringCol == %@", "a")
    let index = allStrings.indexOfObject(allStrings[0] as SwiftStringObject)
    XCTAssertEqual(index, UInt(0))
}