Swift类属性引用在init方法后失效,调用PJSIP方法报内存错误
Hey there! Let's break down what's going on with your PJSIP iOS app. I totally get the frustration when code works in one place but breaks when you refactor it—especially when dealing with C libraries that are picky about memory and pointers.
First, let's recap your issue: When you call the PJSIP registration method directly in your Account class's init(), everything works fine. But when you move that same registration call to a separate register() method, you hit an EXC_BAD_ACCESS code=1 address=0x0 error, which means your code is trying to access a null pointer somewhere.
Likely Causes & Fixes
Let's go through the most probable culprits and how to fix them:
1. Your accCfg struct might be getting corrupted or losing critical data
The error points to a null pointer access, which often happens when a required field in the PJSIP account config (I assume your c_library_type2 maps to pjsua_acc_config) is empty or invalid by the time you call c_register_method.
- Check the config state before registration: Right before calling
register(), log or inspect key fields inaccCfglikereg_uri(registration URI) andid_uri(account ID URI). If either of these isNULLor empty, that's almost certainly the problem. Make sure no other code is modifyingaccCfgbetweeninit()andregister(). - Double-check your init setup: In
init(), you callc_config_setting_defaults(probablypjsua_acc_config_default), which sets sensible defaults. Ensure you're not accidentally overwriting any required fields after this call.
2. Swift value-type memory quirks clashing with C pointers
Since accCfg is a struct (a value type in Swift), there's a chance that when you pass &self.accCfg to the C method in register(), Swift is creating a temporary copy of the struct instead of passing the actual instance's memory. This temporary copy might get deallocated too quickly, leaving PJSIP with a dangling pointer.
Try switching to manual pointer management for the config struct to avoid this:
class Account { var accId: pjsua_acc_id = PJSUA_INVALID_ACC_ID var accCfg: UnsafeMutablePointer<pjsua_acc_config>! init() { // Allocate memory for the config struct accCfg = UnsafeMutablePointer.allocate(capacity: 1) // Initialize with PJSIP defaults pjsua_acc_config_default(accCfg) // Add your other init code here (e.g., setting credentials, URIs) } deinit { // Clean up the allocated memory when the account is deallocated accCfg.deallocate() } public func register() { // Pass the direct pointer to PJSIP let status = pjsua_acc_add(accCfg, PJ_TRUE, &accId) if status != PJ_SUCCESS { // Handle registration failure (log the error code!) print("Registration failed with status: \(status)") } } }
This way, you're explicitly managing the memory for the config struct, ensuring the pointer you pass to PJSIP stays valid as long as the Account instance exists.
3. Thread safety issues
PJSIP requires that most of its API calls are made from the same thread (usually the main thread, or the thread you used to initialize PJSIP). If your init() runs on the main thread but register() is called on a background thread, this can cause memory access errors.
- Verify thread consistency: Make sure both
init()(where you set up PJSIP) andregister()are called from the same thread. You can force this by dispatching theregister()call to the main thread if needed:public func register() { DispatchQueue.main.async { [weak self] in guard let self = self else { return } let status = pjsua_acc_add(&self.accCfg, PJ_TRUE, &self.accId) // Handle status } }
4. PJSIP environment state
Ensure that the PJSIP core is fully initialized and started before you call register(). If your init() includes calls to pjsua_init() and pjsua_start(), make sure those completed successfully, and that the PJSIP environment hasn't been shut down before register() is called.
Quick Debugging Tip
When you hit the EXC_BAD_ACCESS error, use Xcode's debugger to inspect the stack trace. It should point you to exactly which line in the PJSIP code is causing the null pointer access. If it's in the SIP URI handling code, that confirms the issue is with a missing or invalid URI in your accCfg.
Hope these tips help you get your registration working smoothly again!
内容的提问来源于stack exchange,提问作者SEJBR

