logo

English

이곳의 프로그래밍관련 정보와 소스는 마음대로 활용하셔도 좋습니다. 다만 쓰시기 전에 통보 정도는 해주시는 것이 예의 일것 같습니다. 질문이나 오류 수정은 siseong@gmail.com 으로 주세요. 감사합니다.

[iOS/Objective-C] __weak, __block 사용법

by digipine posted Feb 16, 2021
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

일단 위의 __weak나 __block을 사용하는 범위는 block coding을 하는 부분으로 작게만 생각해보도록 합시다.

Block이란?

Objective-C에서 closure의 개념을 도입하기 위해서 만들어진 블럭 코드 부분입니다. 실제로는 이부분은 선언될 경우에 컴파일러에 의해서 __block_literal 이라는 구조체로 만들어진다고 합니다.
이 구조체 안에는 isa정보가 들어가 있어서 Objective-C의 특성을 고스란히 가지게 된다고 합니다.
일단 만들어지게 되면 힙에 생성이 되는게 아니라 스택에서 생성이 된다고 하니 조금 의아하긴 하네요.

__block 키워드

블럭코드를 만들때 어떤식으로 저장해두고 있을지를 정하게 되는 스토리지 타입 변경자라고 합니다.
객체일경우에는 자동으로 retain을 하게 되고, 
객체이고 __block 키워드가 있을 경우에는 retain을 하지 않음... 당연히?
프리미티브타입일 경우에는 const 형태로 value copy가 되고, 프리미티브타입이고 __block 키워드가 붙었을 경우에는 reference형태로 전달되게 된다합니다. 그런데 이 키워드가 중요한 의미는 다음과 같은데요.

1. 블럭내부에서 값의 변경점.

 

1
2
3
4
5
6
7
8
int x = 1;
    
void (^example)(int) = ^(int y) {
    x = x + y; // Error. Variable is not assignable (missing __block type specifier)
    NSLog(@"x = %d, y = %d", x, y);
};
    
example(2);
cs

 

일단 이렇게 코딩 되면 당연히 값이 변경이 안됩니다. 이유는 위에 적은거처럼 값을 만들때 const 형태로 만들어버리기 때문에 변경을 할 수가 없습니다.

 

1
2
3
4
5
6
7
8
__block int x = 1;
    
void (^example)(int) = ^(int y) {
    x = x + y; 
    NSLog(@"x = %d, y = %d", x, y); // success
};
    
example(2);
cs

 

이렇게 만들어버리면 잘 동작을 하겠죠.

 

2. block안에서 상호참조가 발생하는 경우솔찍히 그냥 대충 개발하면 이런거 신경쓰지 않아도 됩니다. 왜냐면 요즘은 폰이 좋아져서 웬만하면 어플이 죽는 문제는 발생하지 않거든요.
그렇지만 우리는 대충 짜는 개발자가 아니기에 이런걸 넘어가면 안됩니다.

* 순환참조
만약에 블럭안에서 self를 참조하는 상황이 발생합니다.
예를 들어 [self test]를 블럭안에서 호출하게 되면 self를 사용하게 되면서, 즉 UIViewController의 retain이 하나 증가하게 됩니다.
이렇게 되는 상황에서 self의 retain이 영원히 0이 되지 않아서 메모리에서 회수가 안되는 부분이 발생하게 되는데요.
이것을 순환참조라고 합니다.
 

그래서 이렇게 쓰지 말고요..

1
2
3
4
5
void (^example)(int) = ^(int y) {
    [self test];
};
    
example(2);
cs

 

이렇게 쓰도록 합니다.

1
2
3
4
5
6
__weak typeof(self) weakSelf = self;
void (^example)(int) = ^(int y) {
    [weakSelf test];
};
    
example(2);
cs

 

자... 마지막으로 블럭을 프로퍼티를 사용할 경우에는 copy를 사용하도록 하는데요.
이유는 블럭 내에서 블럭이 선언될 당시의 스택프레임에 참조하는 변수가 없다면 상관이 없지만 존재하게 된다면 아픔을 느끼게 되기 때문입니다.

1
@property (copy) (^void)exampleBlock(void)
cs

 

이렇게 합시다.

TAG •

List of Articles
No. Subject Author Date Views
50 [iOS] Audio Session Setting digipine 2021.11.26 1
49 [iOS] 개발자를 위한 iOS 15의 새로운 기능 file digipine 2021.11.04 18
48 [iOS/macOS] 사설 인증서를 사용한 SSL HTTPS 통신 시 우회처리 digipine 2021.07.06 356
47 [MacOS] Terminal 에서 zsh compinit: insecure directories 경고 제거하기 lizard2019 2021.04.30 162
46 Concurrent vs Serial DispatchQueue: Concurrency in Swift explained lizard2019 2021.04.16 217
45 WatermelonDB 'jsi/jsi.h' file not found 문제 해결 file digipine 2021.04.06 187
» [iOS/Objective-C] __weak, __block 사용법 digipine 2021.02.16 167
43 macOS ARP Spoofing Attack file digipine 2020.09.17 315
42 The distance estimate iBeacon signal strength lizard2019 2019.10.25 532
41 [MacOS, Swift] 스크롤뷰, NSScrollView 사용법 엉뚱도마뱀 2018.11.01 963
40 [swfit 4] 스위프트 Swift 동시성 동기화 정리 엉뚱도마뱀 2018.09.06 1125
39 [swift 4] 변경 사항 정리 file 엉뚱도마뱀 2018.07.23 867
38 [Objective-C] NSOperation과 NSOperationQueue를 사용하는 방법 - 설명 및 예제 엉뚱도마뱀 2018.03.14 1145
37 MacOS mysql 비밀번호 분실 시 재설정하기 digipine 2017.11.14 700
36 OSX - Screen Serial Terminal - OSX에서 시리얼 터미널 사용하기 digipine 2017.11.03 3937
35 OSX 사파리 최신 버전 폰트 변경하기 file digipine 2017.11.03 1020
34 [Swift 3] TCPIP Socket 통신 클래스 소스 코드 및 사용법 digipine 2017.11.02 3544
33 [Swift 3] HTTP Request 사용하기, 클래스 소스코드 및 사용법 digipine 2017.11.02 3913
32 [macOS] Sandbox 정책 극복기 Accessing Security Scoped Resource file digipine 2017.11.02 1075
31 [Objective C] NSString 앞뒤 공백 문자 및 줄바꿈 문자 제거 digipine 2017.11.02 1213
Board Pagination Prev 1 2 3 Next
/ 3