Realm Swift过滤多个ViewControllers

时间:2017-05-23 07:10:14

标签: ios swift uicollectionview realm filtering

在这里重新提出问题,对代码进行了一些修改:

我有一个名为Galaxies的类,每个类都有一个行星列表

class Galaxy: Object {
  let planets = List<Planet>()
}

class Planet: Object {
  dynamic var capitol = String()
  dynamic var council = String()
  dynamic var collective = String()
  dynamic var signals = String()
}

我有10个视图控制器,每个视图控制器代表一个星系,其中有各种行星特定于该星系。如何过滤特定星系的特定行星?

当我使用隐式展开的可选实例化Results<Galaxy>!实例时,它会在第一个Galaxy VC中编译,因为我的AppDelegate中有启动数据。当我在第二个Galaxy VC中执行此let galaxy = Results<Galaxy>? = nil时,集合视图变为空白。

这是有道理的,因为没有数据。

所以,我想我有两个问题:如何实例化Results对象并过滤每个没有初始数据的视图控制器?

我在galaxies = realm.objects(Galaxy.self).filter("planets == %@", firstPlanet).sorted(byKeyPath: "capitol", ascending: false)中尝试了viewDidLoad(),但这次崩溃了:

libc++abi.dylib: terminating with uncaught exception of type NSException

最后,var galaxy = Results<Galaxy>()引发了异常cannot invoke initializer for type Results with no arguments

2 个答案:

答案 0 :(得分:0)

对于您的视图控制器A从选定的Galaxy传递行星,准备segue方法

using System;
using System.Diagnostics;
using System.Reflection;

// The library that calls Trace, causing the messages you want to suppress.
using NoisyLibrary;

namespace TraceSuppress
{
    /// <summary>
    /// Trace listener that ignores trace messages from a specific assembly.
    /// </summary>
    public class AssemblyFilteredListener : DefaultTraceListener
    {
        private Assembly assemblyToIgnore;

        public AssemblyFilteredListener(Assembly assemblyToIgnoreTracesFrom)
        {
            this.assemblyToIgnore = assemblyToIgnoreTracesFrom;
        }

        public bool TraceIsFromAssemblyToIgnore()
        {
            StackTrace traceCallStack = new StackTrace();

            StackFrame[] traceStackFrames = traceCallStack.GetFrames();

            // Look for the assembly to ignore in the call stack.
            //
            // This may be rather slow for very large call stacks. If you find that this is a bottleneck
            // there are optimizations available.
            foreach (StackFrame traceStackFrame in traceStackFrames)
            {
                MethodBase callStackMethod = traceStackFrame.GetMethod();

                bool methodIsFromAssemblyToIgnore = (callStackMethod.Module.Assembly == this.assemblyToIgnore);

                if (methodIsFromAssemblyToIgnore)
                {
                    return true;
                }

            }

            // The assembly to ignore was not found in the call stack.
            return false;         

        }


        public override void WriteLine(string message)
        {
            if (!this.TraceIsFromAssemblyToIgnore())
            {
                base.WriteLine(message);
            }
        }         

        public override void Write(string message)
        {
            if (!this.TraceIsFromAssemblyToIgnore())
            {
                base.Write(message);
            }
        }
    }

    class Program
    {
        static void SetupListeners()
        {
            // Clear out the default trace listener
            Trace.Listeners.Clear();

            // Grab the asssembly of the library, using any class from the library.
            Assembly assemblyToIgnore = typeof(NoisyLibrary.LibraryClass).Assembly;

            // Create a TraceListener that will ignore trace messages from that library
            TraceListener thisApplicationOnlyListener = new AssemblyFilteredListener(assemblyToIgnore);

            Trace.Listeners.Add(thisApplicationOnlyListener);

            // Now the custom trace listener is the only listener in Trace.Listeners.
        }

        static void Main(string[] args)
        {
            SetupListeners();            

            // Testing
            //-------------------------------------------------------------------------

            // This still shows up in the output window in VS...
            Trace.WriteLine("This is a trace from the application, we want to see this.");

            // ...but the library function that calls trace no longer shows up.
            LibraryClass.MethodThatCallsTrace();

            // Now check the output window, the trace calls from that library will not be present.

        }
    }
}

在视图控制器B中添加

var galaxies:[Galaxy] = realm.objects(Galaxy.self)
var selectedGalaxyIndex = 0
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "segue_for_ViewController_B") {
        // pass data to next view
        let vc = segue.destination as viewControllerB
        vc.planets = galaxies[selectedGalaxyIndex].planets
    }
}

答案 1 :(得分:-1)

如果没有初始数据,Realm查询将为空,这似乎是您想要的。例如:

class Galaxy: Object {
  let planets = List<Planet>()
}

class Planet: Object {
  dynamic var capitol = String()
  dynamic var council = String()
  dynamic var collective = String()
  dynamic var signals = String()
}

let realm = try! Realm()

let galaxies = realm.objects(Galaxy.self)
print(galaxies.count) // => 0

至于你所看到的NSException,我建议你阅读打印到控制台或日志的整条信息,因为这应该告诉你你做错了什么。从您的代码片段开始,firstPlanet可能是nil,这意味着planets == nil是非法查询,因为List属性永远不会为nil。