block 외부 변수 관리에 대한 탐색

4633 단어
데이터 유형은 다음과 같습니다.
  • 국부 변수
  • 정적 변수
  • 글로벌 변수
  • blcok 변수
  • 다음은 코드.
    국부 변수
    //    
    - (void)testLocalData {
        int temp = 10;
        NSLog(@"outside temp --- >%p", &temp);
        int (^sum)(int,int) = ^(int a, int b) {
            NSLog(@"inside temp --- >%p", &temp);
            return temp + a +b;
        };
        temp = 0;
        int c = sum(1,2);
        NSLog(@"last c --- >%d",c);
        
    }
    

    인쇄 결과
    2017-12-27 15:56:52.405071+0800 ManagerBlockMemory[7031:472834] outside temp --- >0x7ffee6bceb2c
    2017-12-27 15:56:56.002926+0800 ManagerBlockMemory[7031:472834] inside temp --- >0x600000447010
    2017-12-27 15:57:04.070374+0800 ManagerBlockMemory[7031:472834] last c --- >13
    (lldb) 
    

    정적 상수
    //    
    - (void)testStaticData {
        static int staticTemp = 10;
        NSLog(@"outside staticTemp --- >%p", &staticTemp);
        int (^sum)(int,int) = ^(int a, int b) {
            NSLog(@"inside staticTemp --- >%p", &staticTemp);
            return staticTemp + a +b;
        };
        staticTemp = 0;
        int c = sum(1,2);
        NSLog(@"last staticTest c --- >%d",c);
    }
    

    인쇄 결과
    2017-12-27 15:59:32.602313+0800 ManagerBlockMemory[7031:472834] outside staticTemp --- >0x109031020
    2017-12-27 15:59:34.118012+0800 ManagerBlockMemory[7031:472834] inside staticTemp --- >0x109031020
    2017-12-27 15:59:35.782439+0800 ManagerBlockMemory[7031:472834] last staticTest c --- >3
    

    전역 변수
    //    
    - (void)testGlobalData {
        NSLog(@"globalData---->%p",&globalTestData);
        int (^sum)(int,int) = ^(int a, int b) {
            NSLog(@"globalData---->%p",&globalTestData);
            return globalTestData + a + b;
        };
        globalTestData = 0;
        int c = sum(1,2);
        NSLog(@"globalData --%d",c);
    }
    
    

    인쇄 결과
    2017-12-27 16:02:58.856153+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
    2017-12-27 16:03:02.124012+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
    2017-12-27 16:03:04.211810+0800 ManagerBlockMemory[7031:472834] globalData --3
    

    block 변수
    //blcok  
    - (void)testBlockData {
        __block int blockData = 10;
        NSLog(@"blockData-- %p",&blockData);
        int (^sum) (int, int) = ^ (int a, int b){
            NSLog(@"blockData-- %p",&blockData);
            return blockData + a + b;
        };
        blockData = 0;
        int c = sum(1,2);
        NSLog(@"blk test c --- %d",c);
    }
    

    인쇄 결과
    2017-12-27 16:04:24.820931+0800 ManagerBlockMemory[7031:472834] blockData-- 0x7ffee6bceb28
    2017-12-27 16:04:27.759598+0800 ManagerBlockMemory[7031:472834] blockData-- 0x604000628078
    2017-12-27 16:04:30.801036+0800 ManagerBlockMemory[7031:472834] blk test c --- 3
    

    위의 4가지 사례열에는 각각 Block에서 만나는 국부 변수, 정적 상수, 전역 변수와 Block 변수에 대한 테스트가 있다.
    전역 변수와 정적 변수 유형을 볼 때 변수의 주소는 변화가 없다. 전역 변수와 정적 변수의 메모리 주소는 고정되어 있기 때문에 Block은 변수를 정의할 때 직접 읽는 메모리 주소이고 복사 변수 값이 없다.
    다시 보면 로컬 변수와 Block 변수는 Block에서 메모리 주소가 바뀌었지만 방법sum()에서 얻은 결과는 다르다.국부 변수에 대해 Block은 정의할 때 복사합니다. 복사된 변수의 메모리 주소가 없습니다. Block에서 상수로 사용되며 수정할 수 없습니다. 그 값은 외부의 영향을 받지 않습니다.
    Block 변수의 경우 주소가 바뀌었지만 BlockData는 외부의 영향을 받았다.BlockData는 변수 자체를 정의할 때 Stack(창고)에 위치하고 Block을 정의할 때 이 변수는 복사된 것이 아니라 컴파일러가 Heap(더미)로 옮겼기 때문에 다음은 테스트 코드입니다.
    - (void)testBlockData {
        __block int blockData = 10;
        NSLog(@"blockData-- %p",&blockData);
        int (^sum) (int, int) = ^ (int a, int b){
            NSLog(@"blockData-- %p",&blockData);
            return blockData + a + b;
        };
        NSLog(@"blockData-- %p",&blockData);
        blockData = 0;
        int c = sum(1,2);
        NSLog(@"blk test c --- %d",c);
    }
    

    다음은 출력
    2017-12-27 16:40:30.971155+0800 ManagerBlockMemory[7445:512216] blockData-- 0x7ffeef5d7b28
    2017-12-27 16:40:30.971420+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
    2017-12-27 16:40:35.657576+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
    2017-12-27 16:40:38.758031+0800 ManagerBlockMemory[7445:512216] blk test c --- 3
    

    요약:
    국부 변수는 값을 전달하는 방식으로 Block에 전달된다.Block 값은 Block에서 사용할 변수를 포획합니다. 국부 변수의 값만 포획하고 메모리 주소가 아니기 때문에 대부분 Block 내부에서 국부 변수의 값을 수정할 수 없습니다.
    Block이 포획한 외부 변수는 정적 변수, Block 변수, 전역 변수를 바꿀 수 있습니다.
    어떤 블로그는 블록에서 변수 값을 바꾸는 두 가지 방식이 있는데 하나는 메모리 주소 바늘을 블록에 전달하는 것이고, 다른 하나는 메모리 영역 방식을 바꾸는 것이다( block) 두 번째는 잘 연구해야 한다고 썼다.
    참조 블로그:
    Block 캡처 외부 변수 및 에 대한 심층 연구block 구현 원리

    좋은 웹페이지 즐겨찾기