在Objective-c问题中使用委托静态方法 [英] Accesing delegate static method in Objective-c issue
问题描述
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(self); //在类方法中注释,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屋!