0

私は一種の辞書であるアプリを書いています - ユーザーに用語のリストを提示し、クリックすると定義を含むダイアログボックスをポップアップします。定義自体にも用語が含まれている場合があり、ユーザーはそれをクリックして別の定義ポップアップを起動できます。

私のメインアプリは「myViewController.m」に保存されています。カスタム UIView クラス 'CustomUIView.m' を呼び出して、定義を表示します (これは、ポップアップするダイアログ ボックスです)。これはすべてうまくいきます。

CustomUIView からのテキスト リンクは、より多くの定義を起動できるはずです。CustomUIView でテキストがタップされると、別の CustomUIView が起動します。問題は、この新しい CustomUIView が、辞書のすべての用語と定義を含むハッシュ マップにアクセスできないことです。これは、私のメイン アプリ 'myViewController.m' でのみ利用できます。

どうにかして、ハッシュ マップのDictionaryHashMap を CustomUIViewクラスのすべてのインスタンスから見えるようにする必要があります。アプリを開いたときにDictionaryHashMap が myViewController.m作成され、その後は変更されません。

同時に開くことができる CustomUIViews の数を制限したくありません (これを行う理由があります! ) 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をグローバルにしようとしました。

  • 「self.dictionaryHashMap」のすべてのインスタンスを「dictionaryHashMap」に変更する
  • 「extern NSMutableDictionary *dictionaryHashMap;」という行を追加します。CustomUIView.h
  • myViewController.mの実装の外側に次を追加します: 'NSMutableDictionary *dictionaryHashMap = nil;'

ただし、dictionaryHashMap は CustomUIView から見えないままです。私が知る限り、実際にはmyViewControllerにローカルな変数のままです...

4

3 に答える 3

3

への参照 (ポインター) を渡すのにリソースを集中的に使用することはありません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];
}
于 2012-11-04T17:17:25.590 に答える
0

mvc パターンが示唆するように、データを常に別のクラスに保持する必要があります。これは、すべての辞書用語にシングルトン クラスを使用し、必要に応じてすべてのカスタム ビューからそれらにアクセスすることで実現できます。

于 2012-11-04T17:22:59.383 に答える
0

シングルトンとして使用するクラスを作成します。

于 2012-11-04T17:16:59.770 に答える