1.OC中有四种方法实现回调,分别是目标-动作对,辅助对象,通知,Block对象
2.目标-动作对,是指当某个事件发生时,向指定对象发送指定消息,计时器使用的就是目标-动作对机制,如下代码所示,每隔两秒会执行一次updateLastTime方法,其中NSRunLoop用来保持线程允许并处理事件
- (void)updateLastTime:(NSTimer *)t{ NSLog(@"timer is %@",t); } #import <Foundation/Foundation.h> #import "MyDesktop.h" int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:desktop selector:@selector(updateLastTime:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run]; } return 0; }
3.辅助对象,是指当某个事件发生时,根据协议(可以理解为Java里的Interface)向辅助对象发送消息,所以辅助对象必须实现要求的协议才能接受消息
//声明 @interface MyDesktop : NSObject<NSURLConnectionDelegate,NSURLConnectionDataDelegate> @end //实现 @implementation MyDesktop - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSLog(@"recevive data size is %ld",[data length]); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"Got it all"); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"%@",[error localizedDescription]); } @end int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; NSURL *url=[NSURL URLWithString:@"http://www.baidu.com"]; NSURLRequest *request=[NSURLRequest requestWithURL:url]; __unused NSURLConnection *coon=[[NSURLConnection alloc] initWithRequest:request delegate:desktop startImmediately:YES]; [[NSRunLoop currentRunLoop] run]; } return 0; }
4.通知,苹果公司提供了一种称为通知中心的对象,可以通过通知中心等待某个通知出现时,向指定的对象发送指定的消息,下面是监听系统时区改变的代码
@interface MyDesktop : NSObject -(void)zoneChanged:(NSNotification *)note; @end @implementation MyDesktop -(void)zoneChanged:(NSNotification *)note{ NSLog(@"zone changed!"); } @end int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:desktop selector:@selector(zoneChanged:) name:NSSystemTimeZoneDidChangeNotification object:nil]; [[NSRunLoop currentRunLoop] run]; } return 0; }
5.Block对象有点像Java里的匿名函数,C里面的函数指针,使用时要注意以下两点
- Block对象中使用外部变量是只读的,如果想修改外部变量,需要在外部变量前面加上__block修饰
- Block对象使用外部变量时,会持有它们(强引用),所以要避免造成强引用循环
int main(int argc, const char * argv[]) { @autoreleasepool { MyDesktop *desktop=[[MyDesktop alloc] init]; //弱引用 __weak MyDesktop *weakDesktop=desktop; //赋值 [desktop setHeight:222]; void (^MyBlock)(NSString *,NSUInteger); MyBlock=^(NSString * str,NSUInteger value){ //避免对象被释放 MyDesktop *innerDesktop=weakDesktop; NSLog(str,innerDesktop.height+value); }; MyBlock(@"test value is %ld",1111); } return 0; }