在Objective-c问题中访问委托静态方法
我在objective-c中遇到了一个奇怪的问题。 这是代码:
STViewController.h
#import @interface STViewController : UIViewController +(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
为什么会这样? 它是否正确? 我没有收到任何错误或警告。 协议方法声明中的 – / +是否有效?
首先,您必须知道一个Class
(通常来自[MyClass class]
)对象也是一个有效的ObjC对象。 这意味着您也可以向类对象发送消息。
例如
@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
所以你可以像其他对象一样使用你的类对象,并像实例方法一样调用类方法。
和类方法实际上是实例方法!! 区别在于类方法是元类的实例方法,它是类的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。
在类方法中, self
指的是类对象。 类对象是一个普通的objc对象(派生自NSObject
),它将接收发送给类的消息(类方法,带有“+”的方法)。
在您的情况下,您使用类对象作为UIAlertView
的委托(这是因为UIAlertView的API没有明确要求静态类型id
的对象)。 现在,警报视图只是将它的委托消息发送到类对象,这也很好,因为您将它们实现为类方法。
你将self
设置为动态的警报委托 – 但是方法调用是静态的,因此首先是错误的,因为当你将调用+ (void)myStaticMethod
未来的某个时候, self
可能是未初始化的并且是nil
。 这就是为什么其他错误可能会跟随未定义的行为
- Swift – UITableView didSelectRowAtIndexPath&didDeselectRowAtIndexPath添加和删除indexPath ID
- 如何复制Xcode项目来创build一个免费的应用程序的付款版本
- iOS前置摄像头仅适用于app
- 迅速。 在模拟器上播放精美的mp3文件,但在设备上播放时没有音量。 AVPlayer
- 在iOS中拨打电话时调用标头的方法是什么?
- 如何录制混音器单元输出产生的声音(iOS Core Audio&Audio Graph)
- CFHTTPMessageAddAuthentication无法向请求添加身份validation数据
- AFNetworking返回400个不好的请求
- 如何在viewController中为自定义UITableViewCell执行操作?