block 외부 변수 관리에 대한 탐색
국부 변수
//
- (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 구현 원리
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.