如何在AppDelegate iPhone应用程序中使用@protocol?
我在5屏幕的iPhone应用程序工作。 我想刷新UITabBarController中第四屏幕的值。 我已经在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
。 你能指导我在哪里做错了吗?
在我的第四个ViewController.h
#import "AppDelegate" @interface fourthViewController : UIViewController <ReloadViewControllerDelegate>
在我的第四个ViewController.m
-(void) refreshViewController:(NSString *)result { NSLog(@"Result : %@", result); }
任何人都可以请帮我做这个? 提前致谢。
你正在调用这个代码:
if ([refreshViewControllerDelegate conformsToProtocol:@protocol(ReloadViewControllerDelegate)])
但是refreshViewControllerDelegate
是这样的:
id refreshViewControllerDelegate;
conformsToProtocol
检查对象是否声明它符合协议,而不是你的协议。 如果您想要指定符合协议,您需要:
id<ReloadViewControllerDelegate> refreshViewControllerDelegate;
编辑
OK,关于performSelectorOnMainThread
问题…该方法在NSThread的类别中提供,并没有在NSObject协议中声明。 所以,如果你想调用它,那么你需要声明你的types为NSObject,它符合你的协议。
NSObject<ReloadViewControllerDelegate> refreshViewControllerDelegate;
编辑
好吧,看起来这不是一个关于使用协议的简单问题,而是一个完整的教程。 既然SO不是这样的地方,我会尽量给出一个简短的…
协议是一个接口声明。
@protocol ReloadChatViewControllerDelegate <NSObject> - (void)refreshViewController:(NSString *)result; @end
这就是说在城里有一个新的协议,名称是ReloadChatViewControllerDelegate
,它也符合NSObject
协议。 任何采用新协议的类都必须提供refreshViewController
的实现。 您可以通过放置@optional
部分来使协议方法成为可选项。
@protocol ReloadChatViewControllerDelegate <NSObject> - (void)refreshViewController:(NSString *)result; @optional - (void)optRefresh; @end
现在,让我们稍后通过协议。 假设你正在编写generics代码,你只是想知道你给的对象是否符合协议,如果是的话,就调用一个方法。 就像是…
@interface Bar : NSObject @property (nonatomic, weak) NSObject<ReloadChatViewControllerDelegate> *refreshViewControllerDelegate; - (void)blarg; @end
现在,Bar类提供了一个委托属性,所以它可以给一些对象来帮助它做一些工作。 但是,该委托对象必须至less是一个NSObject
,并符合ReloadChatViewControllerDelegate
协议。
现在,ObjC(和C)是相当宽容的,所以你可以强制一个对象成为你想要的任何types,但是你应该得到这个崩溃。 现在,当blarg
时,通知代表做一些工作。
由于委托的属性types已经表明它符合给定的协议,所以不需要检查一致性。 我们可以调用委托方法。 请注意,我们必须看看对象是否实现了任何可选的协议方法。
@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(或其他types)。
@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]; } } }
好的,现在你已经定义了一个协议,并且你有调用协议方法的代码。 两个警告。
首先,代表必须设置为一个对象。 对于任何方法, 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];
你需要像这样声明你的委托:
@property (nonatomic, weak) IBOutlet id<ReloadViewControllerDelegate> delegate;
该id将工作,但通过使用<>,您可以确保您分配的委托实际上正在实施该协议,您可能仍然必须确保它响应select器,但只有当某些方法被声明为
@optional
确保你综合它,最重要的是确保你设置它,而不是零。
你得到一个警告,因为你input你的委托作为一个id
。 一个id
是一个genericstypes,这意味着编译器不知道什么方法或属性可用。 为了删除您的警告,请将您的委托声明为NSObject:
@property (nonatomic, retain) NSObject <ReloadViewControllerDelegate> *refreshViewControllerDelegate;
通过声明NSObject,编译器现在知道NSObject所有的方法,然后可以调用:
-performSelectorOnMainThread:withObject:waitUntilDone:
在您的代表没有警告。 祝你好运!
尝试这个:
@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