JSManagedValue를 사용하는 중에 문제가 발생합니다. Session 615 at WWDC 2013을 기반으로 한 내 이해에서 Objective-C와 Javascript 또는 그 반대로의 참조를 원할 때는 Objective-C에 JSValue를 저장하는 대신 JSManagedValue를 사용해야 만 참조주기를 피할 수 있습니다.JSManagedValue를 사용하여 JSValue가 해제되지 않고 참조주기가 발생하지 않도록하려면 어떻게해야합니까?
다음은 내가 시도한 것의 약식 버전입니다. 나는 자바 스크립트 객체에 대한 참조가 필요한 ViewController를 가지고 있으며, 자바 스크립트 객체는 ViewController에서 메서드를 호출 할 수 있어야합니다. ViewController는 카운트를 표시하는 UILabel을 가지고 있으며 두 개의 UIButtons, 'Count'를 증가시키는 'Add', 그리고 새로운 ViewController로 현재 뷰 컨트롤러를 생성하고 대체하는 'Reset'을 가지고 있습니다 (기본적으로 그냥 이전 ViewController 내가 이것을 테스트하는 동안 적절하게 정리된다).
viewDidLoad
에서 ViewController는 updateLabel
을 호출하고 Javascript 개체에서 카운트를 올바르게 가져올 수 있습니다. 그러나, 그 실행 루프가 끝나면, Instruments는 JSValue가 릴리즈되고 있음을 보여줍니다. ViewController는 JSManagedValue와 마찬가지로 여전히 존재하므로 JSValue가 가비지 수집되지 않도록해야한다고 생각 했으니 _managedValue.value
은 이제 nil을 반환합니다.
JSManagedValue를 사용하는 대신 JSValue를 저장하는 경우 시각적으로 모두 작동하지만 예상대로 ViewController와 JSValue 사이에 참조주기가 있으며 Instruments는 ViewController가 절대로 릴리스되지 않는다고 확인합니다.
자바 스크립트 코드 :
(function() {
var _count = 1;
var _view;
return {
add: function() {
_count++;
_view.updateLabel();
},
count: function() {
return _count;
},
setView: function(view) {
_view = view;
}
};
})()
CAViewController.h는
@protocol CAViewExports <JSExport>
- (void)updateLabel;
@end
@interface CAViewController : UIViewController<CAViewExports>
@property (nonatomic, weak) IBOutlet UILabel *countLabel;
@end
CAViewController.m는
@interface CAViewController() {
JSManagedValue *_managedValue;
}
@end
@implementation CAViewController
- (id)init {
if (self = [super init]) {
JSContext *context = [[JSContext alloc] init];
JSValue *value = [context evaluateScript:@"...JS Code Shown Above..."];
[value[@"setView"] callWithArguments:@[self]];
_managedValue = [JSManagedValue managedValueWithValue:value];
[context.virtualMachine addManagedReference:_managedValue withOwner:self];
}
return self;
}
- (void)viewDidLoad {
[self updateLabel];
}
- (void)updateLabel {
JSValue *countFunc = _managedValue.value[@"count"];
JSValue *count = [countFunc callWithArguments:@[]];
self.countLabel.text = [count toString];
}
- (IBAction)add:(id)sender {
JSValue *addFunc = _managedValue.value[@"add"];
[addFunc callWithArguments:@[]];
}
- (IBAction)reset:(id)sender {
UIApplication *app = [UIApplication sharedApplication];
CAAppDelegate *appDelegate = app.delegate;
CAViewController *vc = [[CAViewController alloc] init];
appDelegate.window.rootViewController = vc;
}
무엇입니까 JSValue가 ViewController의 수명 내내 유지되지만 ViewController를 정리할 수 있도록 참조주기가 생성되지 않도록이 설정을 처리하는 올바른 방법은 무엇입니까?
나는 이것이 정확하다고 생각합니다. 나는 세션 615의 비디오에서 소스 코드를 읽음으로써이를 확인해야만한다. 샘플 프로젝트가 여전히 유용하다면 좋을 것이다. – Poulsbo
샘플 코드는 현재 이곳에 있습니다 : https://developer.apple.com/downloads/index.action?name=WWDC%202013 – Poulsbo