티스토리 뷰
1. 간단한 Retain Cycle
@interface Item : NSObject @property (nonatomic, strong) Item* value1; @property (nonatomic, strong) Item* value2; @end - (void)someMethod { Item *a1 = [[Item alloc] init]; Item *a2 = [[Item alloc] init]; a1.value2 = a2; } |
|
||||||
@interface Item : NSObject @property (nonatomic, strong) Item* value1; @property (nonatomic, strong) Item* value2; @end - (void)someMethod { Item *a1 = [[Item alloc] init]; Item *a2 = [[Item alloc] init]; a1.value2 = a2; a2.value1 = a1; } |
각각의 객체 참조 카운트가 2가 되며, a1, a2 가 함수 끝에 다다라 소멸해도 참조 카운트가 하나씩 남아있다. |
||||||
@interface Item : NSObject @property (nonatomic, weak) Item* value1; @property (nonatomic, strong) Item* value2; @end - (void)someMethod { Item *a1 = [[Item alloc] init]; Item *a2 = [[Item alloc] init]; a1.value2 = a2; a2.value1 = a1; } |
|
2. Delegate 에서의 Retain Cycle
@interface TestViewController : UIViewController <TestCellDelegate> - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cell.delegate = self; } #pragma mark - TestCellDelegate - (void)doSomething:(TestCell *)cell { } @interface TestCell : UITableViewCell @property (nonatomic, strong) id<TestCellDelegate> delegate; @end |
doSomething 에 따라 달라지겠지만, 기본적으로 tableView 에서도 TestCell Object 를 가지고있을 수도 있다. 참조카운트가 2 이상이라면 retain cycle 이 발생한다. |
3. Block 에서의 Retain Cycle
@interface ViewController : UIViewController @property (nonatomic, strong) Item *model; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _model = [[Item alloc] init]; _model.myBlock1 = ^{ [self print]; }; _model.myBlock1(); } - (void)print { NSLog(@"print"); } |
왼쪽 코드에서는 실제로 메모리 릭이 발생하지는 않는다. 하지만 model Object 가 self 에 의해서 retain 되게 된다면, retain cycle 발생 가능성이 있다. | ||||||
@interface ViewController : UIViewController @property (nonatomic, strong) Item *model; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; __weak ViewController *weakSelf = self; _model = [[Item alloc] init]; _model.myBlock1 = ^{ [weakSelf print]; }; _model.myBlock1(); } - (void)print { NSLog(@"print"); } |
retain cycle 발생 가능성을 없애기 위해 __weak 으로 형변환하여 block 내부에서 호출해준다. | ||||||
@interface ViewController : UIViewController @property (nonatomic, strong) Item *model; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; __weak ViewController *weakSelf = self; _model = [[Item alloc] init]; _model.myBlock1 = ^{ __strong ViewController *strongSelf = weakSelf; [weakSelf print]; }; _model.myBlock1(); } - (void)print { NSLog(@"print"); } | __weak Object 의 경우 언제 nil 이 될지 모른다. 댕글링 포인터로 인한 Crash 방지를 위해 block 내부에서는 __strong Object 로 다시 형변환하여 block 내부에서 호출해준다. |
4. 참고
http://rakuraku.tistory.com/67
http://rhammer.tistory.com/97
'iOS 개발 > ObjectiveC' 카테고리의 다른 글
NSArray, NSMutableArray, NSString, NSNumber (0) | 2016.07.24 |
---|---|
GCD 기본 (0) | 2016.07.24 |
- Total
- Today
- Yesterday
- coredata
- RunLoop
- dictionary
- set
- workerThread
- 읽기 좋은 코드가 좋은 코드다
- HTTP
- Swift
- NSManagedObject
- NSManagedObjectModel
- CIImage
- ios
- Swfit
- Swift3
- NSManagedObjectContext
- EffectiveObjectiveC
- UIView
- CGImage
- AWS
- delegate
- thread
- optional
- 꺼내먹어요
- Swift 3.0
- Arc
- Block
- applicationWillResignActive
- string
- docker
- Swift 3
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |