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
56 Core Audio를 사용하여 macOS에서 Audio를 Capture하는 코드 digipine 2024.04.19 462
55 macOS Daemon 관련 시스템 폴더 목록 lizard2019 2024.03.08 469
54 Firebase 'GoogleUtilities/GULURLSessionDataResponse.h' file not found Error Fix lizard2019 2023.07.04 632
53 [macOS] Xcode 디버깅 시 Could not attach pid 오류 해결 file lizard2019 2023.06.05 1347
52 [macOS, iOS] 개발자 정보 확인하는 명령어 digipine 2023.03.23 419
51 [macOS] 현재 사용 중인(열려있는) 포트 확인하고 Close 하기 digipine 2022.10.24 622
50 [iOS] Audio Session Setting digipine 2021.11.26 712
49 [iOS] 개발자를 위한 iOS 15의 새로운 기능 file digipine 2021.11.04 758
48 [iOS/macOS] 사설 인증서를 사용한 SSL HTTPS 통신 시 우회처리 digipine 2021.07.06 3639
47 [MacOS] Terminal 에서 zsh compinit: insecure directories 경고 제거하기 lizard2019 2021.04.30 832
46 Concurrent vs Serial DispatchQueue: Concurrency in Swift explained lizard2019 2021.04.16 668
45 WatermelonDB 'jsi/jsi.h' file not found 문제 해결 file digipine 2021.04.06 942
» [iOS/Objective-C] __weak, __block 사용법 digipine 2021.02.16 5809
43 macOS ARP Spoofing Attack file digipine 2020.09.17 934
42 The distance estimate iBeacon signal strength lizard2019 2019.10.25 932
41 [MacOS, Swift] 스크롤뷰, NSScrollView 사용법 엉뚱도마뱀 2018.11.01 1733
40 [swfit 4] 스위프트 Swift 동시성 동기화 정리 엉뚱도마뱀 2018.09.06 1571
39 [swift 4] 변경 사항 정리 file 엉뚱도마뱀 2018.07.23 1291
38 [Objective-C] NSOperation과 NSOperationQueue를 사용하는 방법 - 설명 및 예제 엉뚱도마뱀 2018.03.14 4495
37 MacOS mysql 비밀번호 분실 시 재설정하기 digipine 2017.11.14 1239
Board Pagination Prev 1 2 3 Next
/ 3