我正在尝试启动一个在块中NSObject
调用的子类。应该是直到我将它设置在块中。我需要在这个块中设置它,因为在我显示后我将它保存在方法中FormObject
JavascriptCore
FormObject
nil
JavascriptCore
UIActionSheet
FormObject
UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
这是代码:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (actionSheet.tag == kSaveFormConfirmationActionSheetTag) {
if ([ButtonTitle isEqualToString:NSLocalizedString(@"Yes", @"Yes")]) {
NSLog(@"Saving form data");
NSLog(@"%@",formData);
NSLog(@"%@",formData.dictionary);
if (formData) {
[[AutoFillManager defaultManager] saveFormData:formData];
formData = nil;
}
}
else if ([ButtonTitle isEqualToString:NSLocalizedString(@"Never for this Website", @"Never for this Website")]) {
NSString *formURLString = [formData.urlString copy];
formData = nil;
formData = [[FormObject alloc] initWithDisabledSite:formURLString];
[[AutoFillManager defaultManager] saveFormData:formData];
formData = nil;
}
else {
self.formData = nil;
}
}
}
- (JSContext *)getCurrentJavascriptContext {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"JSTools" ofType:@"js"];
NSString *scriptString = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:nil];
[context evaluateScript:scriptString];
context[@"print"] = ^(NSString *string) {
NSLog(@"%@",string);
};
__weak AutoFillManager *afm = [AutoFillManager defaultManager];
__weak UIToolbar *weakToolbar = toolbar;
__weak typeof(self) weakSelf = self;
context[@"receiveForm"] = ^(NSString *urlString, NSString *username, NSString *usernameFieldID, NSString *usernameFieldName, NSString *password, NSString *passwordFieldID, NSString *passwordFieldName) {
NSURL *url = [NSURL URLWithString:urlString];
for (NSDictionary *savedForm in [afm savedForms]) {
FormObject *form = [[FormObject alloc] initWithFormDictionary:savedForm];
if ([[url host] isEqualToString:form.urlString] && [username isEqualToString:form.username] && form.neverForThisSite == NO) {
#ifdef DEBUG
NSLog(@"Site already saved");
#endif
return;
}
if ([[url host] isEqualToString:form.urlString] && form.neverForThisSite == YES) {
#ifdef DEBUG
NSLog(@"Never for this site");
#endif
return;
}
}
formData = [[FormObject alloc] initWithUsername:username withUsernameID:usernameFieldID withUsernameName:usernameFieldName withPassword:password withPasswordID:passwordFieldID withPasswordName:passwordFieldName withURLString:[url host]];
UIActionSheet *saveFormConfirmationActionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Would you like to save this password?", @"Would you like to save this password?")] delegate:weakSelf cancelButtonTitle:NSLocalizedString(@"Not Now", @"Not Now") destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Yes", @"Yes"), NSLocalizedString(@"Never for this Website", @"Never for this Website"), nil];
saveFormConfirmationActionSheet.tag = kSaveFormConfirmationActionSheetTag;
[saveFormConfirmationActionSheet showFromToolbar:weakToolbar];
};
return context;
}
我知道问题是因为
formData = [[FormObject alloc] initWithUsername:username withUsernameID:usernameFieldID withUsernameName:usernameFieldName withPassword:password withPasswordID:passwordFieldID withPasswordName:passwordFieldName withURLString:[url host]];
如果我添加说明符,__weak
Xcode 会警告我将其更改为__block
. 如果我将其更改为__block
thenformData
仍将是nil
之后。
如何正确设置此块中的 ivar?
解决方案
解决方案是使 ivar 成为一个属性并使用弱 self 来设置该属性。
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([ButtonTitle isEqualToString:NSLocalizedString(@"Never for this Website", @"Never for this Website")]) {
NSString *formURLString = [self.formData.urlString copy];
self.formData = nil;
self.formData = [[FormObject alloc] initWithDisabledSite:formURLString];
[[AutoFillManager defaultManager] saveFormData:self.formData];
self.formData = nil;
}
else {
self.formData = nil;
}
}
}
- (JSContext *)getCurrentJavascriptContext {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"JSTools" ofType:@"js"];
NSString *scriptString = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:nil];
[context evaluateScript:scriptString];
context[@"print"] = ^(NSString *string) {
NSLog(@"%@",string);
};
__weak AutoFillManager *afm = [AutoFillManager defaultManager];
__weak UIToolbar *weakToolbar = toolbar;
__weak typeof(self) weakSelf = self;
context[@"receiveForm"] = ^(NSString *urlString, NSString *username, NSString *usernameFieldID, NSString *usernameFieldName, NSString *password, NSString *passwordFieldID, NSString *passwordFieldName) {
NSURL *url = [NSURL URLWithString:urlString];
for (NSDictionary *savedForm in [afm savedForms]) {
FormObject *form = [[FormObject alloc] initWithFormDictionary:savedForm];
if ([[url host] isEqualToString:form.urlString] && [username isEqualToString:form.username] && form.neverForThisSite == NO) {
#ifdef DEBUG
NSLog(@"Site already saved");
#endif
return;
}
if ([[url host] isEqualToString:form.urlString] && form.neverForThisSite == YES) {
#ifdef DEBUG
NSLog(@"Never for this site");
#endif
return;
}
}
weakSelf.formData = [[FormObject alloc] initWithUsername:username withUsernameID:usernameFieldID withUsernameName:usernameFieldName withPassword:password withPasswordID:passwordFieldID withPasswordName:passwordFieldName withURLString:[url host]];
UIActionSheet *saveFormConfirmationActionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Would you like to save this password?", @"Would you like to save this password?")] delegate:weakSelf cancelButtonTitle:NSLocalizedString(@"Not Now", @"Not Now") destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Yes", @"Yes"), NSLocalizedString(@"Never for this Website", @"Never for this Website"), nil];
saveFormConfirmationActionSheet.tag = kSaveFormConfirmationActionSheetTag;
[saveFormConfirmationActionSheet showFromToolbar:weakToolbar];
};
return context;
}