我正在编写一个词典的应用程序 - 它为用户提供了术语列表,然后单击时,弹出一个包含定义的对话框。定义本身也可能包含术语,而用户可以单击以启动另一个定义弹出。
。我的主应用程序存储在'MyViewController.m'中。它调用自定义Uiview类" customuiview.m"以显示定义(这是弹出的对话框)。这一切都很好。
然后,从自定义图表中的文本链接应该能够启动更多定义。当我的CustomUiview敲击文本时,它将启动另一个自定义图。问题是,这个新的CustomUiview无法访问包含我所有字典的术语和定义的哈希地图。这仅适用于我的主应用程序" myviewController.m'。
以某种方式,我需要制作我的哈希地图, dictionaryhashmap ,对于 customuiview 类的每个实例都可以看到。 dictionaryhashmap 是在应用程序打开并在此后不更改时在 myViewController.m 中创建的。
我不想限制可以同时打开的自定义数量的数量(我有这样做的理由!),因此发送的副本是有点大量资源dictionaryhashmap to customUiview的每个实例。据推测,解决方案是将 dictionaryhashmap 成为全局变量。
我的一些代码:
来自myViewController.m:
- (void)viewDidLoad
{
self.dictionaryHashMap = [[NSMutableDictionary alloc] init]; // initialise the dictionary hash map
//... {Code to populate dictionaryHashMap}
}
// Method to pop up a definition dialog
- (void)displayDefinition:(NSString *) term
{
NSArray* definition = [self.dictionaryHashMap objectForKey:term]; // get the definition that corresponds to the term
CustomUIView* definitionPopup = [[[CustomUIView alloc] init] autorelease]; // initialise a custom popup
[definitionPopup setTitle: term];
[definitionPopup setMessage: definition];
[definitionPopup show];
}
// Delegation for sending URL presses in CustomUIView to popupDefinition
#pragma mark - CustomUIViewDelegate
+ (void)termTextClickedOn:(CustomUIView *)customView didSelectTerm:(NSString *)term
{
myViewController *t = [[myViewController alloc] init]; // TODO: This instance has no idea what the NSDictionary is
[t displayDefinition:term];
}
来自customuiview.m:
// Intercept clicks on links in UIWebView object
- (BOOL)webView: (UIWebView*)webView shouldStartLoadWithRequest: (NSURLRequest*)request navigationType: (UIWebViewNavigationType)navigationType {
if ( navigationType == UIWebViewNavigationTypeLinkClicked ) {
[myViewController termTextClickedOn:self didSelectTerm:request];
return NO;
}
return YES;
}
关于如何使 dictionaryhashmap 可见的任何提示 CustomUiview 都将不胜感激。
我尝试通过执行以下操作来制作 dictionaryhashmap global:
- 将'self.dictionaryhashmap'的所有实例更改为'dictionaryhashmap'
- 添加" extern nsmutabledictionary *dictionaryhashmap;'到 customuiview.h
- 在 myviewController.m 中添加以下内容:'nsmutabledictionary *dictionaryHashmap = nil;'
但是,字典hashmap仍然不可见。据我所知,它实际上仍然是一个变量,该变量是 myviewController ...
将参考(指针)传递给dictionaryHashMap
不是资源密集的。指向对象的指针仅为4个字节。您可以将其从视图控制器传递给视图。
但是我不知道你为什么还需要这样做。单击项时,您的视图将消息(termTextClickedOn:didSelectTerm:
)发送到视图控制器。而且View Controller已经对字典有一个引用,因此可以处理查找。为什么视图还需要引用字典?
无论如何,如果要使字典成为全局,则在 application:didFinishLaunchingWithOptions:
中将其初始化它在您的应用程序委托中进行初始化是更合适的。您甚至可以使字典成为您的应用程序代表的属性,并懒洋洋地将其初始化。
更新
我没有注意到您的评论termTextClickedOn:didSelectTerm:
是类方法。我认为这是一种实例方法,因为myViewController
从下案字母开始,iOS编程中的惯例是类是从大写字母开始的。(您可以在遵循大会时更容易获得良好的帮助!)
这是我建议的。首先,将myViewController
重命名为MyViewController
(或更好,DefinitionViewController
)。
将其属于引用字典的属性。无论代码创建的新实例MyViewController
都负责设置此属性。
给出目标和动作的CustomUIView
属性:
@property (nonatomic, weak) id target;
@property (nonatomic) SEL action;
创建视图时设置这些属性:
- (void)displayDefinition:(NSString *)term {
NSArray* definition = [self.dictionaryHashMap objectForKey:term];
CustomUIView* definitionPopup = [[[CustomUIView alloc] init] autorelease]; // initialise a custom popup
definitionPopup.target = self;
definitionPopup.action = @selector(termWasClicked:);
...
在视图的webView:shouldStartLoadWithRequest:
方法中,从URL请求中提取术语,然后将其发送到目标/操作:
- (BOOL)webView: (UIWebView*)webView shouldStartLoadWithRequest: (NSURLRequest*)request navigationType: (UIWebViewNavigationType)navigationType {
if ( navigationType == UIWebViewNavigationTypeLinkClicked ) {
NSString *term = termForURLRequest(request);
[self.target performSelector:self.action withObject:term];
return NO;
}
return YES;
}
在视图控制器的termWasClicked:
方法中,创建新视图控制器并设置其字典属性:
- (void)termWasClicked:(NSString *)term {
MyViewController *t = [[MyViewController alloc] init];
t.dictionary = self.dictionary;
[t displayDefinition:term];
}
创建将用作单身人士的类。示例。
您应该始终将数据保存在单独的类中,如MVC模式所暗示的建议,并且可以通过在所有字典术语中使用Singleton类来实现,并在需要时从每个自定义视图中访问它们。