在Objective-c问题中使用委托静态方法 [英] Accesing delegate static method in Objective-c issue

查看:219
本文介绍了在Objective-c问题中使用委托静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在目标c中有一个奇怪的问题。以下是代码:



STViewController.h

  #import< ; UIKit / UIKit.h> 
@interface STViewController:UIViewController< UIAlertViewDelegate>
+(void)myStaticMethod;
@end

STViewController.m

  #importSTViewController.h

@implementation STViewController

- (void)viewDidLoad
{
[super viewDidLoad];

[STViewController myStaticMethod];
}

+(void)myStaticMethod {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@Foo bar
message:@baz bat
//在这种情况下,self甚至意味着什么?类对象STViewController?
委托:self
cancelButtonTitle:@取消
otherButtonTitles:@OK,nil];
[alert show];
[alert release];
}

#pragma mark UIAlertViewDelegate

// TRICKY PART如果它是静态的,如果不是,它不会。
//即使协议声明实例方法(带负号)。
+(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(@It works!);
}

@end

为什么会发生这种情况?它是否正确?我没有收到任何错误或警告。协议方法声明中的 - / +是否有作用?

解决方案

首先,你必须知道一个 class (通常从 [MyClass class] 获取)对象也是一个有效的ObjC对象。这意味着您也可以发送消息到类对象。



例如

  @interface MyClass:NSObject 
+(NSString *)name;
@end

@implementation MyClass
+(NSString *)name {
return NSStringFromClass(s​​elf); //在类方法中注释,self == [MyClass class]
}
@end

// -------在某些方法中

id cls = [MyClass class]; //正确的类型应该是Class,但是由于Class是一个对象,id也可以工作
NSLog(@%@,[cls name]); //调用像实例方法 - MyClass
NSLog(@%@,[MyClass name]); //调用像类方法 - MyClass

所以你可以像其他对象一样使用你的类对象,并调用类方法如实例方法。



和类方法实际上是实例方法!不同的是,类方法是元类的实例方法,它是 Class 的类。更多关于元类: http:// www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html






也是,你的类接口是不正确的,因为它不可能(至少在编译时)将一个协议添加到元类。所以如果你做 [self conformsToProtocol:@protocol(UIAlertViewDelegate)] 将返回NO。但是您实现了 + alertView:clickedButtonAtIndex:,它将添加此方法作为元类的实例方法,因此代理代码工作, [self responseToSelector: @selector(alertView:clickedButtonAtIndex:)] 将返回YES。


I have a weird problem in objective-c. Here is the code:

STViewController.h

#import <UIKit/UIKit.h>
@interface STViewController : UIViewController <UIAlertViewDelegate>
+(void)myStaticMethod;
@end

STViewController.m

#import "STViewController.h"

@implementation STViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [STViewController myStaticMethod];
}

+ (void)myStaticMethod {
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Foo bar"
                                                    message:@"baz bat"
    //what does self even mean in this context? The class object STViewController?
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"OK", nil];
    [alert show];
    [alert release];
}

#pragma mark UIAlertViewDelegate

// TRICKY PART if it's static it works, if it's not, it doesn't.
// even though the protocol declares instance methods (with a minus).
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSLog(@"It works!");
}

@end

Why does this happen? Is this correct? I receive no errors or warnings. Does the -/+ in the protocol methods declaration do something?

解决方案

First, you have to know that a Class (normally get from [MyClass class]) object is also an valid ObjC object. This means that you can send message to class object as well.

For example

@interface MyClass : NSObject
+ (NSString *)name;
@end

@implementation MyClass
+ (NSString *)name {
    return NSStringFromClass(self); // note in class method, self == [MyClass class]
}
@end

// ------- in some method

id cls = [MyClass class]; // the correct type should be Class, but since Class is an object, id will also work
NSLog(@"%@", [cls name]); // call like instance method - MyClass
NSLog(@"%@", [MyClass name]); // call like class method - MyClass

so you can use your class object like other object and call the class method like instance method.

and class methods are actually instance methods!! the difference is that class methods are instance methods of metaclass, which is the class of Class. for more about metaclass: http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html


also, your class interface is incorrect, because it is not possible (at least at compiler time) to add a protocol to a metaclass. so if you do [self conformsToProtocol:@protocol(UIAlertViewDelegate)] will return NO. but you implemented + alertView:clickedButtonAtIndex: which will add this method as the instance method of the metaclass, so the delegate code works and [self responseToSelector:@selector(alertView:clickedButtonAtIndex:)] will return YES.

这篇关于在Objective-c问题中使用委托静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆