Recently, I encountered a callback for IOS projects, so I took the time to sort out the relevant information. The following is the sorting content:
Callback
A callback is to bind an executable piece of code to a specific event. This code is executed when a specific event occurs.
In Objective-C, there are four ways to implement callbacks.
Target-action pair
Before the program starts to wait, it is required that "when time occurs, send a specific information to the specified object." Here the object that receives the message is the target, and the message selector is the action.
Auxiliary object
Before the program starts waiting, it is required to "send a message to the auxiliary object that complies with the corresponding protocol when time occurs." Delegate objects and data sources are common helper objects.
notify
Apple provides an object called Notification Center. Before the program starts waiting, you can inform the notification center that "an object is waiting for certain specific notifications. When one of the notifications appears, a specific message is sent to the specified object." When an event occurs, the relevant object will issue a notification to the Notification Center, and the Notification Center will forward the notification to the object waiting for the notification.
Block object
Block is a piece of executable code. Before the program starts waiting, declare a Block object, and execute this Block object when the event occurs.
NSRunLoop
There is an NSRunLoop class in iOS. The NSRunLoop instance will continue to wait. When a specific event occurs, a message will be sent to the corresponding object. An NSRunLoop instance triggers a callback when a specific event occurs.
cycle
Before implementing a callback, you need to create a loop:
int main(int argc, const char * argv[]) { @autoreleasepool { [[NSRunLoop currentRunLoop]run]; } return 0; }
Target-action pair
Create an application with NSRunLoop objects and NSTimer objects. Every two seconds, the NSTimer object will send the specified action message to its target, creating a new class named BNRLogger, which is the target of the NSTimer object.
Declare the action method in:
#import <Foundation/> @interface BNRLogger : NSObject<NSURLSessionDataDelegate> @property(nonatomic) NSDate *lastTime; -(NSString *) lastTimeString; -(void)updateLastTime: (NSTimer *) t; @end
Implementation method in:
#import "" @implementation BNRLogger -(NSString *)lastTimeString { static NSDateFormatter *dateFormatter=nil; if(!dateFormatter) { dateFormatter =[[NSDateFormatter alloc]init]; [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; NSLog(@"created dateFormatter"); } return [dateFormatter stringFromDate:]; } -(void)updateLastTime:(NSTimer *)t { NSDate *now=[NSDate date]; [self setLastTime:now]; NSLog(@"Just set time to %@",); } @end
Create a BNRLogger instance in:
#import <Foundation/> #import "" int main(int argc, const char * argv[]) { @autoreleasepool { BNRLogger *logger=[[BNRLogger alloc]init]; __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:logger selector:@selector(updateLastTime:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop]run]; } return 0; }
Auxiliary object
My previous blog has written about the use of the NSURLSession method, so the use of the helper object callback will turn the BNRLogger object into the delegate object of the NSURLSession. When a specific event occurs, the object will send a message to the helper object.
Create an NSURL object and an NSURLRequest object in it. Then create an NSURLSession object and set the instance of BNRLogger to its
Delegation object:
#import <Foundation/> #import "" int main(int argc, const char * argv[]) { @autoreleasepool { BNRLogger *logger=[[BNRLogger alloc]init]; //The URL is a download link for an image NSURL *url = [NSURL URLWithString:@"/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%%2Fuploads%2F2016%2F0914%&thumburl=http%3A%2F%%2Fit%2Fu%3D2349180720%2C2436282788%26fm%3D11%26gp%"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; __unused NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:logger delegateQueue:[NSOperationQueue mainQueue]]; __unused NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:logger selector:@selector(updateLastTime:) userInfo:nil repeats:YES]; //4. Create a Task based on the session object (send a request) NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request]; //5. Execute tasks [dataTask resume]; [[NSRunLoop currentRunLoop]run]; } return 0; }
In, declare the NSURLSessionDataDelegate protocol:
#import <Foundation/> @interface BNRLogger : NSObject<NSURLSessionDataDelegate> @property (nonatomic, strong) NSMutableData *responseData; @property(nonatomic) NSDate *lastTime; -(NSString *) lastTimeString; -(void)updateLastTime: (NSTimer *) t; @end
There is the proxy method of NSURLSession. For details, you can see NSURLSession:
#import "" @implementation BNRLogger -(NSMutableData *)responseData { if (_responseData == nil) { _responseData = [NSMutableData data]; } return _responseData; } -(NSString *)lastTimeString { static NSDateFormatter *dateFormatter=nil; if(!dateFormatter) { dateFormatter =[[NSDateFormatter alloc]init]; [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; NSLog(@"created dateFormatter"); } return [dateFormatter stringFromDate:]; } -(void)updateLastTime:(NSTimer *)t { NSDate *now=[NSDate date]; [self setLastTime:now]; NSLog(@"Just set time to %@",); } //1. Call this method when receiving the server response-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { //In this method, you can get the response header information, that is, the response NSLog(@"didReceiveResponse--%@",[NSThread currentThread]); NSLog(@"response"); //Note: You need to use the completionHandler callback to tell the system how to process the data returned by the server. //Cancel by default /* NSURLSessionResponseCancel = 0, default processing method, cancel NSURLSessionResponseAllow = 1, receive data returned by the server NSURLSessionResponseBecomeDownload = 2, becomes a download request NSURLSessionResponseBecomeStream becomes a stream */ completionHandler(NSURLSessionResponseAllow); } //2. This method will be called when receiving the server's return data. If the data is large, the method may be called multiple times.-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { NSLog(@"didReceiveData--%@",[NSThread currentThread]); NSLog(@"return"); //The data returned by the splicing server [ appendData:data]; } //3. This method will be called when the request completes (success|failed). If the request fails, the error has a value-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"didCompleteWithError--%@",[NSThread currentThread]); NSLog(@"Finish"); if(error == nil) { //Analyze the data NSDictionary *dict = [NSJSONSerialization JSONObjectWithData: options:kNilOptions error:nil]; NSLog(@"%@",dict); } } @end
notify
When the system time zone changes, an NSSystemTimeZoneDidChangeNotification notification will be issued to the Notification Center, and the Notification Center will forward the notification to the corresponding observer.
Register the BNRLogger instance as an observer. If the system time zone settings change, you can receive corresponding notifications:
//Include this line of code in the "Helpful Object" method application [[NSNotificationCenter defaultCenter]addObserver:logger selector:@selector(zoneChange:) name:NSSystemTimeZoneDidChangeNotification object:nil];
Implement this method in:
//Include this line of code in the "Helpful Object" method application -(void)zoneChange:(NSNotification *)note { NSLog(@"The system time zone has changed!"); }
Block callback
Put the "notification" method mentioned above in the application:
[[NSNotificationCenter defaultCenter]addObserver:logger selector:@selector(zoneChange:) name:NSSystemTimeZoneDidChangeNotification object:nil];
Change to:
[[NSNotificationCenter defaultCenter]addObserverForName:NSSystemTimeZoneDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note){ NSLog(@"The system time zone has changed!"); }];
Remove this method from the "notification" method application:
-(void)zoneChange:(NSNotification *)note { NSLog(@"The system time zone has changed!"); }
Summarize
- For objects that do only one thing (for example), use the target-action pair.
- For more complex objects (such as NSURLSession), use helper objects. The most common type of helper object is the delegate object.
- For objects (such as NSTimeZone) that want to trigger multiple (in other objects) callbacks, use notifications.
- Block implements callbacks to make the code easy to read.
Thank you for reading, I hope it can help you. Thank you for your support for this site!