美文网首页
iOS 在debug和release下的ARC

iOS 在debug和release下的ARC

作者: fulen | 来源:发表于2018-10-19 15:17 被阅读34次

    最近公司项目遇到一个问题,线上的app不能收到聊天记录,以往的版本中都是OK的,但是最近的一个版本没法收到通知,究其原因是因为在release环境下的内存管理问题,下面直接上代码

    - (void)invokeEvent:(NSString *)eventName withArgs:(NSArray *)args {
        SRSubscription *eventObj = _subscriptions[eventName];
        if(eventObj != nil && eventObj.object != nil) {
            NSMethodSignature *signature = [eventObj.object methodSignatureForSelector:eventObj.selector];
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
            NSUInteger numberOfArguments = [signature numberOfArguments] - 2;
            
            if (args.count != numberOfArguments) {
                SRLogConnectionInfo(@"Callback for event '%@' is configured with %ld arguments, received %ld parameters instead.",eventName, (unsigned long)numberOfArguments, (unsigned long)args.count);
            }
            
            [invocation setSelector:eventObj.selector];
            [invocation setTarget:eventObj.object];
            for(int i =0; i< MIN([args count], numberOfArguments); i++) {
                int arguementIndex = 2 + i;
                __weak NSString *argument = args[i];
                [invocation setArgument:&argument atIndex:arguementIndex];
            }
            [invocation invoke];
        }
    }
    
    

    以上是第三方库signalR的部分代码,我们在__weak NSString *argument = args[i];做了部分修改,我们想传递一个数组出去,于是修改成如下代码

    - (void)invokeEvent:(NSString *)eventName withArgs:(NSArray *)args {
        SRSubscription *eventObj = _subscriptions[eventName];
        if(eventObj != nil && eventObj.object != nil) {
            
            NSMethodSignature *signature = [eventObj.object methodSignatureForSelector:eventObj.selector];
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
            NSUInteger numberOfArguments = [signature numberOfArguments] - 2;
            
            if (args.count != numberOfArguments) {
                SRLogConnection(@"Callback for event '%@' is configured with %ld arguments, received %ld parameters instead.",eventName, (unsigned long)numberOfArguments, (unsigned long)args.count);
            }
            
            [invocation setSelector:eventObj.selector];
            [invocation setTarget:eventObj.object];
            for(int i =0; i< MIN([args count], numberOfArguments); i++) {
                int arguementIndex = 2 + i;
                __weak id argument = [OSPJSONUtil objectFromJSONValue:args[i] class:eventObj.argClasses[i]];
                [invocation setArgument:&obj atIndex:arguementIndex];
            }
            [invocation invoke];
        }
    }
    

    问题来了,第三方库signalR内部做了内存管理,将我们上面创建的对象加入到autoreleasepool中了,在debug环境下是没有问题的,但是上线release就会导致argument--weak之后立马释放,而导致取不到值

    2、我们新建一个项目测试一下

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSArray *arr = @[@"testArray",@"testArray",@"testArray"];
        __weak NSArray *testArray = arr;
        NSLog(@"testArray=%@, &testArray=%p, &arr=%p",testArray,testArray,arr);
        
        __weak NSArray *testArray1 = @[@"testArray1",@"testArray1",@"testArray1"];
        NSLog(@"testArray1=%@",testArray1);
        
        @autoreleasepool {
            __weak NSArray *testArray2 = @[@"testArray2",@"testArray2",@"testArray2"];
            NSLog(@"testArray2=%@",testArray2);
            
            NSArray *arr = @[@"testArray3",@"testArray3",@"testArray3"];
            __weak NSArray *testArray3 = arr;
            NSLog(@"testArray3=%@ ,&testArray=%p, &arr=%p",testArray3,testArray3,arr);
            
            __weak NSString *testString = @"testString";
            NSLog(@"testString=%@",testString);
            
        }
    }
    // 以上是release模式下的代码,下面附带截图
    
    release模式

    可以看到在testArray1 和testArray2处有两个警告,意思是对象在创建完成后会被立马释放掉,我们看下打印结果


    release模式打印结果

    接下来我们切换到debug模式,以下为debug模式打印结果


    debug模式打印结果

    结论:
    release模式下,__weak 创建的对象会被立刻释放掉,但是NSString对象不会被立刻释放掉,
    debug模式下,__weak 创建的对象不会被立刻释放掉

    相关文章

      网友评论

          本文标题:iOS 在debug和release下的ARC

          本文链接:https://www.haomeiwen.com/subject/ezgyzftx.html