You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4中尝试将Realm数据库对象用作实例变量的问题

Troubleshooting Your Swift 4 Code: Initialization, Realm & RxSwift Integration

Hey there! Let's walk through the issues in your code and get things working smoothly, especially since you're transitioning from Java to Swift.

Core Issue in Your Current Code

The biggest problem right now is that your mTestResult property is an optional TestRes?, and you're trying to assign to self.mTestResult?.id without first initializing the TestRes instance. If mTestResult is nil (which it is by default), that line of code does nothing—no error, but no value gets set either. That's why your print statement is probably showing nil for the test ID.

Fix 1: Properly Initialize TestRes

You have two solid options here:

Option A: Make mTestResult a Non-Optional Property

If TestRes should always exist when ClassA is initialized, initialize it directly:

public class ClassA { // Swift convention: capitalize class names
    var mTestResult: TestRes = TestRes() // Initialize immediately
    func setTestResult(measurement: Measurement){ 
        self.mTestResult.id = measurement.measurementId 
        print("Test Id: \(self.mTestResult.id)") 
        print("Measurement Id: \(measurement.measurementId)") // Verify the source value
    } 
}

Option B: Initialize TestRes When Needed

If mTestResult might not exist until a measurement comes in, check and initialize it inside the method:

public class ClassA {
    var mTestResult: TestRes? 
    func setTestResult(measurement: Measurement){ 
        // Create a TestRes instance if one doesn't exist yet
        if self.mTestResult == nil {
            self.mTestResult = TestRes()
        }
        self.mTestResult?.id = measurement.measurementId 
        print("Test Id: \(self.mTestResult?.id)") 
    } 
}

Fix 2: Update ClassA from ClassB

To set ClassA's variable from ClassB, you need a reference to a ClassA instance in ClassB. Here's how to do it:

  1. Add a property in ClassB to hold the ClassA instance:
public class ClassB {
    var classAInstance: ClassA? // Store a reference to your ClassA object
    // ... your other Bluetooth/RxSwift code
}
  1. When you have a Measurement object in ClassB, call the setTestResult method:
// Inside ClassB, when you get a new Measurement
if let classA = classAInstance {
    classA.setTestResult(measurement: newMeasurement)
}

Bonus: RxSwift-Friendly Approach

Since you're using RxSwift for Bluetooth communication, a reactive pattern will make this cleaner. Here's how to wire it up:

  1. In ClassB, create a Subject to broadcast new Measurement objects:
import RxSwift

public class ClassB {
    let measurementSubject = PublishSubject<Measurement>()
    let disposeBag = DisposeBag()
    // ... your Bluetooth code that emits measurements
    // When you get a measurement, send it through the subject:
    // measurementSubject.onNext(newMeasurement)
}
  1. In ClassA, subscribe to this subject to automatically update mTestResult:
import RxSwift

public class ClassA {
    var mTestResult: TestRes = TestRes()
    let disposeBag = DisposeBag()

    func bind(to classB: ClassB) {
        classB.measurementSubject
            .subscribe(onNext: { [weak self] measurement in
                guard let self = self else { return }
                self.mTestResult.id = measurement.measurementId
                print("Updated Test Id: \(self.mTestResult.id)")
            })
            .disposed(by: disposeBag)
    }
}
  1. Connect them somewhere (like your view controller or app setup):
let classA = ClassA()
let classB = ClassB()
classA.bind(to: classB)

Realm Integration Notes

Since you're storing these objects in Realm:

  • Ensure TestRes is a subclass of Object:
    import RealmSwift
    
    class TestRes: Object {
        @objc dynamic var id: String = "" // Use appropriate type for your measurementId
        // Add other Realm properties here
    
        override static func primaryKey() -> String? {
            return "id" // If id should be the primary key
        }
    }
    
  • When updating mTestResult for Realm, make sure you're doing it inside a write transaction if needed:
    let realm = try! Realm()
    try! realm.write {
        self.mTestResult.id = measurement.measurementId
    }
    

Quick Swift Convention Tip

Remember that Swift uses capitalized class names (e.g., ClassA instead of classA)—this makes your code more readable and aligns with standard Swift practices.

内容的提问来源于stack exchange,提问作者Aaron Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:55:26