Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
646 views
in Technique[技术] by (71.8m points)

ios - Do we have to use explicit autorelease pool when using Realm in GCD even under ARC

It is said in Realm's doc:

You may also see this problem when accessing Realm using Grand Central Dispatch. This can happen when a Realm ends up in a dispatch queue’s autorelease pool as those pools may not be drained for some time after executing your code. The intermediate versions of data in the Realm file cannot be reused until the RLMRealm object is deallocated. To avoid this issue, you should use an explicit autorelease pool when accessing a Realm from a dispatch queue.

Does this mean that we must use explicit autorelease pool everytime in GCD even under ARC? Can someone post a code sample? This is kind of important, but the official documentation does not emphasize it so much

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You don't really have to use an explicit autorelease pool every time. It is more relevant for scenarios where you do a lot of concurrent transactions and could easily run into the risk of tracking to many immediate versions. Or when you want to make sure that you close the Realm file in the lifetime of your app by releasing all open accessors to it.

The docs are at this point more to understand as a making aware of technical limitations and a hint how to resolve that once you hit an issue like that than a general best practice. Sure, you could always do that and it wouldn't necessarily hurt you (à la "If you have a hammer, everything looks like a nail."), but you wouldn't necessarily have to do it.

The extra complication of what this exactly means is not required for everyone. Understanding explicit autorelease pools needs a deeper understanding of ARC that is not a general requirement. If you have ideas, how that could be resolved in a better way, your feedback is more than welcome.

The section Using a Realm Across Threads gives an example for that, inserting a million objects in a background queue:

dispatch_async(queue) {
  autoreleasepool {
    // Get realm and table instances for this thread
    let realm = try! Realm()

    // Break up the writing blocks into smaller portions
    // by starting a new transaction
    for idx1 in 0..<1000 {
      realm.beginWrite()

      // Add row via dictionary. Property order is ignored.
      for idx2 in 0..<1000 {
        realm.create(Person.self, value: [
          "name": "(idx1)",
          "birthdate": NSDate(timeIntervalSince1970: NSTimeInterval(idx2))
        ])
      }

      // Commit the write transaction
      // to make this data available to other threads
      try! realm.commitWrite()
    }
  }
}

It generally makes sense to have object creations in a number like that in a separate autoreleasepool as you can't really predict with ARC when the object releases will happen and so you have an explicit point in time, when they will happen latest, which makes your program more deterministically to understand for you and other humans.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...