0

我正在编写一个应用程序,它是一种字典 - 它为用户提供一个术语列表,当点击时,会弹出一个包含定义的对话框。定义本身也可能包含术语,而用户又可以单击这些术语来启动另一个定义弹出窗口。

我的主应用程序存储在“myViewController.m”中。它调用一个自定义 UIView 类“CustomUIView.m”来显示定义(这是弹出的对话框)。这一切都很好。

然后来自 CustomUIView 的文本链接应该能够启动更多定义。在我的 CustomUIView 中点击文本时,它会启动另一个 CustomUIView。问题是,这个新的 CustomUIView 无法访问包含我的所有字典术语和定义的哈希映射;这仅适用于我的主应用程序“myViewController.m”。

不知何故,我需要使我的哈希映射dictionaryHashMap对CustomUIView类的每个实例可见。dictionaryHashMap在应用程序打开时在myViewController.m中创建,此后不会更改。

我不希望限制可以同时打开的 CustomUIView 的数量(我有这样做的理由!),因此将dictionaryHashMap的副本发送到自定义UIView。想必,解决的办法就是让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成为全局:

  • 将“self.dictionaryHashMap”的所有实例更改为“dictionaryHashMap”
  • 添加行'extern NSMutableDictionary *dictionaryHashMap;' 到CustomUIView.h
  • 在myViewController.m的实现之外添加以下内容:'NSMutableDictionary *dictionaryHashMap = nil;'

但是,dictionaryHashMap 对 CustomUIView 仍然不可见。据我所知,它实际上仍然是myViewController本地的一个变量......

4

3 回答 3

3

将引用(指针)传递给dictionaryHashMap. 指向对象的指针只有 4 个字节。您可以将它从您的视图控制器传递到您的视图。

但我不知道为什么你甚至需要这样做。termTextClickedOn:didSelectTerm:当单击一个术语时,您的视图正在向视图控制器发送一条消息 ( )。并且视图控制器已经有了对字典的引用,所以它可以处理查找。为什么视图还需要引用字典?

无论如何,如果你想让字典成为一个全局的,在你的应用程序委托中初始化它会更合适,在application:didFinishLaunchingWithOptions:. 你甚至可以让字典成为你的应用程序委托的一个属性并懒惰地初始化它。

更新

termTextClickedOn:didSelectTerm:直到您的评论是类方法,我才注意到。我假设它是一个实例方法,因为myViewController以小写字母开头,而 iOS 编程中的约定是类以大写字母开头。(当您遵循约定时,您更容易获得良好的帮助!)

这是我推荐的。首先,重命名myViewControllerMyViewController(或更好的,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];
}
于 2012-11-04T17:17:25.590 回答
0

创建一个将用作单例的类。例子

于 2012-11-04T17:16:59.770 回答
0

您应该始终按照 mvc 模式的建议将数据保存在单独的类中,这可以通过对所有字典术语使用单例类并在需要时从每个自定义视图中访问它们来实现。

于 2012-11-04T17:22:59.383 回答