在Objective-C中设置/获取全局变量



我正在编写一个词典的应用程序 - 它为用户提供了术语列表,然后单击时,弹出一个包含定义的对话框。定义本身也可能包含术语,而用户可以单击以启动另一个定义弹出。

我的主应用程序存储在'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类来实现,并在需要时从每个自定义视图中访问它们。

最新更新