이것은 나에게도 문제가 되었기 때문에 다른 답변을 게시하는 중입니다. 원래 블록 내부에 자체 참조가있는 곳이라면 어디에서나 blockSelf를 사용해야한다고 생각했습니다. 이것은 사실이 아니며, 객체 자체에 블록이있는 경우에만 해당됩니다. 사실,이 경우 blockSelf를 사용하면 블록에서 결과를 다시 가져 오기 전에 객체가 할당 해제 될 수 있으며 호출하려고 할 때 충돌이 발생하므로 응답 할 때까지 분명히 자신을 유지하기를 원합니다 돌아오다.
첫 번째 경우는 블록에서 참조되는 블록을 포함하므로 보유주기가 발생하는시기를 보여줍니다.
#import <Foundation/Foundation.h>
typedef void (^MyBlock)(void);
@interface ContainsBlock : NSObject
@property (nonatomic, copy) MyBlock block;
- (void)callblock;
@end
@implementation ContainsBlock
@synthesize block = _block;
- (id)init {
if ((self = [super init])) {
//__block ContainsBlock *blockSelf = self; // to fix use this.
self.block = ^{
NSLog(@"object is %@", self); // self retain cycle
};
}
return self;
}
- (void)dealloc {
self.block = nil;
NSLog (@"ContainsBlock"); // never called.
[super dealloc];
}
- (void)callblock {
self.block();
}
@end
int main() {
ContainsBlock *leaks = [[ContainsBlock alloc] init];
[leaks callblock];
[leaks release];
}
두 번째 경우에는 blockSelf가 필요하지 않습니다. 호출하는 객체에는 자체를 참조 할 때 유지주기가 발생하는 블록이 없기 때문입니다.
#import <Foundation/Foundation.h>
typedef void (^MyBlock)(void);
@interface BlockCallingObject : NSObject
@property (copy, nonatomic) MyBlock block;
@end
@implementation BlockCallingObject
@synthesize block = _block;
- (void)dealloc {
self.block = nil;
NSLog(@"BlockCallingObject dealloc");
[super dealloc];
}
- (void)callblock {
self.block();
}
@end
@interface ObjectCallingBlockCallingObject : NSObject
@end
@implementation ObjectCallingBlockCallingObject
- (void)doneblock {
NSLog(@"block call complete");
}
- (void)dealloc {
NSLog(@"ObjectCallingBlockCallingObject dealloc");
[super dealloc];
}
- (id)init {
if ((self = [super init])) {
BlockCallingObject *myobj = [[BlockCallingObject alloc] init];
myobj.block = ^() {
[self doneblock]; // block in different object than this object, no retain cycle
};
[myobj callblock];
[myobj release];
}
return self;
}
@end
int main() {
ObjectCallingBlockCallingObject *myObj = [[ObjectCallingBlockCallingObject alloc] init];
[myObj release];
return 0;
}
self
프록시 를 부르는 것을 좋아합니다this
. JavaScript에서는this
클로저를 호출self
하므로 멋지고 균형 잡힌 느낌입니다. :)