Memory management issue while Call Obj-C in Swift

I'm currently developing a native plugin for a Capcitor app. I have very little experience with native iOS development, Swift and Obj-C.

I use a framework (FunSDK) which is written in C++.

I call this in an Objective-C++ wrapper.

As described here: https://medium.com/@cecilia.humlelu/set-up-c-library-dependencies-in-swift-projects-5dc2ccd2ddaf

The wrapper is then available in Swift via the bridging header.

This works so far, I can call the functions from the framework and they are executed correctly.

However, the functions of the framework are executed asynchronously. When a result is obtained, the “OnFunSDKResult” method is always executed.

During this step I get an EXC_BAD_ACCESS error while debugging. Then I ticked “Zombie objects” under the diagnostics settings. This causes execution to stop with an EXC_BREAKPOINT.

As I understand it, after executing the iniXMSDK method, the FunSDKWrapper class is cleared from memory before executing the "OnFunSDKResult" method?

I have also already integrated a completionHandler, which is only called in the "OnFunSDKResult" method so that data is transferred to the Swift class. However, that doesn't help either.

I have no idea how to proceed.

I hope somebody can help me.

If you need any more information, I would be happy to provide it.

The FunSDKWrapper.mm


//

//  FunSDKWrapper.m

//  App

//

//  Created by Sysprobs on 12/8/23.

//



#import "FunSDKWrapper.h"

#import "FunSDK/FunSDK.h"



#import <XMNetInterface/Reachability.h>



@implementation FunSDKWrapper



-(NSString *)iniXMSDK:(int)test completion:(void (^)(int result))completionHandler{

    

    self.initCompletionHandler = completionHandler;

    

    self.msgHandle = FUN_RegWnd((__bridge void *)self);

    

    FUN_Init();

    Fun_LogInit(self.msgHandle, "", 0, "", LOG_UI_MSG);

    FUN_XMCloundPlatformInit("***", "***", "***", 1);

    FUN_InitNetSDK();

    

    FUN_SetFunStrAttr(EFUN_ATTR_SAVE_LOGIN_USER_INFO,SZSTR([self GetDocumentPathWith:@"UserInfo.db"]));

        

    FUN_SetFunStrAttr(EFUN_ATTR_USER_PWD_DB, SZSTR([self GetDocumentPathWith:@"password.txt"]));

    

    FUN_SetFunStrAttr(EFUN_ATTR_UPDATE_FILE_PATH,SZSTR([self GetDocumentPathWith:@""]));

    FUN_SetFunStrAttr(EFUN_ATTR_TEMP_FILES_PATH,SZSTR([self GetDocumentPathWith:@""]));

        

    FUN_SetFunIntAttr(EFUN_ATTR_AUTO_DL_UPGRADE, 0);

    

    FUN_SetFunStrAttr(EFUN_ATTR_CONFIG_PATH,SZSTR([self GetDocumentPathWith:@"APPConfigs"]));

    

    FUN_SetFunIntAttr(EFUN_ATTR_SUP_RPS_VIDEO_DEFAULT, 1);

    

    FUN_SetFunIntAttr(EFUN_ATTR_SET_NET_TYPE, [self getNetworkType]);

    

    FUN_SysInit("arsp.xmeye.net;arsp1.xmeye.net;arsp2.xmeye.net", 15010);

    FUN_InitNetSDK();



    FUN_SysGetDevList(self.msgHandle, SZSTR(@"xxxx") , SZSTR(@"xxxx"),0);

        

    return @"test";

}



- (void)searchLanDevices {

     FUN_DevSearchDevice(self.msgHandle, 4000, 0);

}





// NSDocument/fileName

- (NSString *)GetDocumentPathWith:(NSString *) fileName {

    NSString* path = [self documentsPath];

    if (fileName != nil) {

        path = [path stringByAppendingString:@"/"];

        path = [path stringByAppendingString:fileName];

    }

    return path;

}

//NSDocument

- (NSString *)documentsPath {

    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *path = [pathArray lastObject];

    return path;

}



-(int)getNetworkType {

    Reachability*reach=[Reachability reachabilityWithHostName:@"www.apple.com"];

    

    //判断当前的网络状态

    switch([reach currentReachabilityStatus]){

            

        case ReachableViaWiFi:

            return 1;

            

        case ReachableViaWWAN:

            return 2;

            

        default:

            return 0;

            break;

    }

}





- (void)OnFunSDKResult:(NSNumber *) pParam {

    NSInteger nAddr = [pParam integerValue];

    MsgContent *msg = (MsgContent *)nAddr;

    switch (msg->id) {

        case EMSG_SYS_GET_DEV_INFO_BY_USER:{

            self.initCompletionHandler(1);	

            if (msg->param1 < 0){

                //fehler

                NSLog(@"Fehler beim XMCloud login");

            }else{

                

                char devJson[750*500];

                FUN_GetFunStrAttr(EFUN_ATTR_GET_USER_ACCOUNT_DATA_INFO, devJson, 750*500);

                NSLog(@"Geraeteliste: = %s",devJson);

            }

        }

        break;

    }

}





@end

The Swift Class


import Foundation

import Capacitor



/**

 * Please read the Capacitor iOS Plugin Development Guide

 * here: https://capacitorjs.com/docs/plugins/ios

 */

@objc(xmsdkPlugin)

public class xmsdkPlugin: CAPPlugin {

    private let implementation = xmsdk()



    @objc func echo(_ call: CAPPluginCall) {

        let value = call.getString("value") ?? ""

        call.resolve([

            "value": implementation.echo(value)

        ])

    }

    

    @objc func initXMSDK(_ call: CAPPluginCall) {

        //let devId = call.getString("devId") ?? ""

        

           

        let wrapper = FunSDKWrapper();

        let resp = wrapper.iniXMSDK(1, completion: {(result) -> Void in

            NSLog("Completion von iniXMSDK")

        });

        

        call.resolve([

            "status": resp

        ])



    }    

    

}

Errorlog with EXC_BREAKPOINT:

-OnFunSDKResult: is an Objective-C method. Who is actually calling that? It can’t be the FunSDK itself because that’s in C++. And I don’t see any other references to it in the code that you posted.

Also, when you stop at that trap, what does the backtrace look like? To get a text backtrace, which is much more useful that a screen shot, enter backtrace into the debugger prompt.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Memory management issue while Call Obj-C in Swift
 
 
Q