1

私は5つの画面を持つiPhoneアプリで作業しています。UITabBarControllerで画面4番目の値を更新したい。AppDelegate に @protocol を追加しましたが、呼び出していません。@protocol を使用するのはこれが初めてですが、この問題の解決を手伝っていただけませんか。

AppDelegate.h

@protocol ReloadViewControllerDelegate <NSObject>

-(void) refreshViewController:(NSString *)result;

@end

id refreshViewControllerDelegate;

@property (nonatomic, retain) id refreshViewControllerDelegate;

そして合成しました。

AppDelegare.m

@synthesize refreshViewControllerDelegate;

if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) 
{
   [refreshViewControllerDelegate performSelectorOnMainThread:@selector(refreshViewController:) withObject:@"YES" waitUntilDone:NO];                
}// Control not come inside of if Condition.... From here i want to update the fourthViewController..

しかしcontrol not go inside of the if condition。どこが間違っているのか教えてください。

私の4番目のViewController.hで

#import "AppDelegate"

@interface fourthViewController : UIViewController <ReloadViewControllerDelegate>

私の4番目のViewController.mで

-(void) refreshViewController:(NSString *)result
{
    NSLog(@"Result : %@", result);
}

誰でも私がこれを行うのを手伝ってもらえますか? 前もって感謝します。

4

4 に答える 4

0

次のようにデリゲートを宣言する必要があります。

@property (nonatomic, weak) IBOutlet id<ReloadViewControllerDelegate> delegate;

IDは機能しますが、<>を使用することで、割り当てたデリゲートが実際にプロトコルを実装していることを確認できます。セレクターに応答することを確認する必要がある場合がありますが、それは一部のメソッドが次のように宣言されている場合のみです。

@optional

あなたがそれを合成することを確認してください、そして最も重要なことはあなたがそれを設定することを確認してください、そしてそれはゼロではありません。

于 2012-08-17T12:33:09.887 に答える
0

これを試して:

@protocol ReloadViewControllerDelegate <NSObject>

-(void) refreshViewController:(NSString *)result;

@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (weak) id <ReloadViewControllerDelegate>refreshViewControllerDelegate;
@end

AppDelegate.m 内

@implementation AppDelegate
@synthesize window, refreshViewControllerDelegate;

...

ここで Tab4ViewController はクラスの名前です。

    if ([Tab4ViewController conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) 
    {
       [refreshViewControllerDelegate performSelectorOnMainThread:@selector(refreshViewController:) withObject:@"YES" waitUntilDone:NO];                
    }

...
@end


#import "AppDelegate.h"

@interface Tab4ViewController<ReloadViewControllerDelegate>
...
@end

@implementation Tab4ViewController

...
appDelegate.refreshViewControllerDelegate = self;
...

@end
于 2012-08-17T13:41:51.303 に答える
0

デリゲートを として入力しているため、警告が表示されますid。Anidはジェネリック型です。つまり、コンパイラは、どのメソッドやプロパティが利用可能かを認識していません。警告を削除するには、デリゲートを NSObject として宣言します。

@property (nonatomic, retain) NSObject <ReloadViewControllerDelegate> *refreshViewControllerDelegate;

NSObject として宣言することで、コンパイラは NSObject が持っているすべてのメソッドを認識するようになり、次の呼び出しが可能になります。

-performSelectorOnMainThread:withObject:waitUntilDone:

警告なしでデリゲートに。幸運を!

于 2012-08-17T13:06:35.943 に答える
-1

このコードを呼び出しています:

if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)]) 

しかしrefreshViewControllerDelegate、これは次のとおりです。

id refreshViewControllerDelegate;

conformsToProtocolオブジェクトがプロトコルに準拠していることを宣言しているかどうかを確認しますが、あなたのものはそうではありません。プロトコルへの準拠を指定する場合は、次のことを行う必要があります。

id<ReloadViewControllerDelegate> refreshViewControllerDelegate;

編集

OK、performSelectorOnMainThread問題について... そのメソッドは NSThread のカテゴリで提供されており、NSObject プロトコルでは宣言されていません。したがって、それを呼び出したい場合は、型をプロトコルに準拠した NSObject として宣言する必要があります。

NSObject<ReloadViewControllerDelegate> refreshViewControllerDelegate;

編集

OK、これはプロトコルの使用に関する単純な質問ではなく、完全なチュートリアルのようです。SOはそのような場所ではないので、簡単に説明します...

プロトコルはインターフェイス宣言です。

@protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
@end

それは、名前の付いた新しいプロトコルが町にあり、ReloadChatViewControllerDelegateそれもプロトコルに準拠していることを示していNSObjectます。新しいプロトコルを採用するすべてのクラスは、 の実装を提供する必要がありますrefreshViewController。セクションを入れることで、プロトコルメソッドをオプションにすることができます@optional

@protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
@optional
- (void)optRefresh;
@end

さて、プロトコルの採用については後回しにしましょう。汎用コードを書いていて、与えられたオブジェクトがプロトコルに準拠しているかどうかを知りたいだけで、準拠している場合はメソッドを呼び出すとします。何かのようなもの...

@interface Bar : NSObject
@property (nonatomic, weak) NSObject<ReloadChatViewControllerDelegate>  *refreshViewControllerDelegate;
- (void)blarg;
@end

現在、Bar クラスはデリゲート プロパティを提供しているため、何らかの作業を行うのに役立つオブジェクトを与えることができます。ただし、そのデリゲート オブジェクトは、少なくとも であり、プロトコルNSObjectに準拠している必要があります。ReloadChatViewControllerDelegate

現在、ObjC (および C) は非常に寛容であるため、オブジェクトを強制的に任意の型にすることができますが、クラッシュするのは当然のことです。blargが呼び出されると、デリゲートは何らかの作業を行うように通知されます。

デリゲートのプロパティ タイプは、指定されたプロトコルに準拠していると既に述べているため、準拠を確認する必要はありません。デリゲート メソッドを呼び出すだけです。オブジェクトがオプションのプロトコル メソッドを実装しているかどうかを確認する必要があることに注意してください。

@implementation Bar
@synthesize refreshViewControllerDelegate = _refreshViewControllerDelegate;
- (void)blarg {
    // Do something, then invoke the delegate
    [self.refreshViewControllerDelegate
        performSelectorOnMainThread:@selector(refreshViewController:)
                         withObject:@"YES"
                      waitUntilDone:NO];
    if ([self.refreshViewControllerDelegate respondsToSelector:@selector(optRefresh)]) {
        [self.refreshViewControllerDelegate optRefresh];
    }
}
@end

ただし、一般的であり、任意のオブジェクトをデリゲートとして受け入れたい場合 (デリゲートが特定のプロトコルに準拠することをオプションにしたい場合もあります)、プレーンを受け入れてidから、それが準拠しているかどうかを確認できます。その場合、デリゲートを単なる id (または他の型) として宣言できます。

@property (nonatomic, weak) id refreshViewControllerDelegate;

ここで、コード内で適合性をチェックする必要があります。

- (void)blarg {
    // Do something, then invoke the delegate
    if ([self.refreshViewControllerDelegate
            conformsToProtocol:@protocol(ReloadChatViewControllerDelegate)]) {
        [self.refreshViewControllerDelegate
            performSelectorOnMainThread:@selector(refreshViewController:)
                             withObject:@"YES" waitUntilDone:NO];
        if ([self.refreshViewControllerDelegate
                respondsToSelector:@selector(optRefresh)]) {
            [self.refreshViewControllerDelegate optRefresh];
        }
    }
}

OK、これでプロトコルが定義され、プロトコルでメソッドを呼び出すコードができました。2 つの注意事項。

まず、デリゲートをオブジェクトに設定する必要があります。 nilはどのメソッドにも応答するfalseため、もちろん準拠せず、メッセージが送信されても​​何もしません。

次に、デリゲートがプロトコルへの準拠を宣言していることを確認する必要があります。メソッドを実装するだけでは適合しません。クラスがプロトコルに準拠していることを明示的に指定していない場合、conformsToProtocolプロトコルのメソッドを実装していても false を返します。

そこで、プロトコルに準拠してデリゲートとして機能するクラスを指定しましょう。

@interface Foo : NSObject<ReloadChatViewControllerDelegate>
- (void)refreshViewController:(NSString *)result;
@end
@implementation Foo
- (void)refreshViewController:(NSString *)result {
    NSLog(@"Look, ma, I'm refreshed with %@", result);
}
@end

プロトコルに準拠し、必須メソッドの実装を提供し、オプションのメソッドを省略します。

さて、このコードを実行すると、素晴らしいコードが見事に表示されるはずです。

Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] init];
bar.refreshViewControllerDelegate = foo;
[bar blarg];
于 2012-08-17T12:32:18.193 に答える