Recently to do the iOS project encountered a callback, time to put the relevant information, the following is the content:
Callback
A callback is the binding of a piece of executable 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 requires "to send a specific message to the specified object when it occurs." The object that receives the message here is the target, and the selector of the message is the action.
Secondary objects
Before the program begins to wait, the request "sends a message to a secondary object that complies with the protocol when it occurs." delegate objects and data sources are common secondary objects.
Notice
Apple offers an object called a notification center. Before the program starts waiting, you can tell the notification center that an object is waiting for certain notifications. Sends a specific message to the specified object when one of the notifications appears. When an event occurs, the related object publishes a notification to the Notification center, which then forwards the notification to the object that is waiting for the notification.
Block Object
Block is a piece of executable code. Declare a block object before the program begins to wait, and execute the blocks object when the event occurs.
Nsrunloop
There is a Nsrunloop class in iOS, Nsrunloop instances will continue to wait, and when a particular event occurs, a message is sent to the corresponding object. The Nsrunloop real example triggers a callback when a particular event occurs.
Cycle
Before you implement a callback, you create a loop:
int main (int argc, const char * argv[]) {
@autoreleasepool {[
nsrunloop currentrunloop]run];
}
return 0;
}
Target-Action Pair
Create an application that has Nsrunloop objects and Nstimer objects. Every two seconds, the Nstimer object sends the specified action message to its target, creating a new class named Bnrlogger, which is the target of the Nstimer object.
To declare an action method in BNRLogger.h:
#import <Foundation/Foundation.h>
@interface bnrlogger:nsobject<nsurlsessiondatadelegate>
@ Property (nonatomic) NSDate *lasttime;
-(NSString *) lasttimestring;
-(void) Updatelasttime: (Nstimer *) T;
@end
Implementing Methods in BNRLOGGER.M:
#import "BNRLogger.h"
@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:self.lastTime];
}
-(void) Updatelasttime: (Nstimer *) t
{
nsdate *now=[nsdate Date];
[Self setlasttime:now];
NSLog (@ "Just set time to%@", self.lasttimestring);
}
@end
Create a Bnrlogger instance in MAIN.M:
#import <Foundation/Foundation.h>
#import "BNRLogger.h"
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;
}
Secondary objects
My last blog has written about the use of the Nsurlsession method, then the use of the helper object callback, the Bnrlogger object becomes the delegate object of the Nsurlsession, and when a particular event occurs, the object sends a message to the secondary object.
Create a Nsurl object and Nsurlrequest object in the MAIN.M. Then create a Nsurlsession object that sets the instance of Bnrlogger to its
Delegate object:
#import <Foundation/Foundation.h> #import "BNRLogger.h" int main (int argc, const char * argv[]) {@autoreleasepo
OL {Bnrlogger *logger=[[bnrlogger alloc]init]; URL is a picture of the download link nsurl *url = [Nsurl urlwithstring:@ yun_qi_img/error.html&thumburl=http%3a%2f%
2fimg4.imgtn.bdimg.com%2fit%2fu%3d2349180720%2c2436282788%26fm%3d11%26gp%3d0.jpg "];
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 (send request) Nsurlsessiondatatask *datatask = [session Datataskwithrequest:request] based on conversation object;
5. Implementation of the mandate [Datatask resume];
[[Nsrunloop Currentrunloop]run];
return 0;
}
BNRLogger.h, declare the Nsurlsessiondatadelegate protocol:
#import <Foundation/Foundation.h>
@interface bnrlogger:nsobject<nsurlsessiondatadelegate>
@ Property (Nonatomic, Strong) Nsmutabledata *responsedata;
@property (nonatomic) nsdate *lasttime;
-(NSString *) lasttimestring;
-(void) Updatelasttime: (Nstimer *) T;
@end
BNRLOGGER.M, there are nsurlsession agent methods, can be seen in detail nsurlsession:
#import "BNRLogger.h" @implementation Bnrlogger-(Nsmutabledata *) ResponseData {if (_responsedata = = nil) {_res
Ponsedata = [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:self.lastTime];
}-(void) Updatelasttime: (Nstimer *) T {nsdate *now=[nsdate date];
[Self setlasttime:now];
NSLog (@ "Just set time to%@", self.lasttimestring); //1 This method is called when a server response is received-(void) Urlsession: (Nsurlsession *) session Datatask: (Nsurlsessiondatatask *) datatask Didreceiveresponse: (nsurlresponse *) response Completionhandler: (void (^) (nsurlsessionresponsedisposition)) Completionhandler {//In this method can get the response header information, namely Response NSLog (@ "didreceiveresponse--%@", [Nsthread CurrentThread]);
NSLog (@ "response"); Note: You need to use the Completionhandler callback to tell the system how to handle the data returned by the server///default is canceled/* nsurlsessionresponsecancel = 0, default processing, cancellation Nsurlse Ssionresponseallow = 1, the data returned by the receiving server Nsurlsessionresponsebecomedownload = 2, becomes a download request Nsurlsessionresponsebecomestr
EAM into a stream * * Completionhandler (Nsurlsessionresponseallow); //2. This method is invoked when the server returns data, and if the data is large then the method may be invoked multiple times-(void) Urlsession: (Nsurlsession *) session Datatask: ( Nsurlsessiondatatask *) Datatask didreceivedata: (NSData *) data {NSLog (@ "didreceivedata--%@", [Nsthread CurrentThread]
);
NSLog (@ "return");
Splicing data returned by the server [Self.responsedata Appenddata:data]; //3. This method is called when the request completes (Success | fails) and if the request fails, the error has a value-(void) Urlsession: (Nsurlsession *) session Task: (Nsurlsessiontask *) task
Didcompletewitherror: (Nserror *) error {NSLog (@ "didcompletewitherror--%@", [Nsthread CurrentThread]);
NSLog (@ "complete"); if (Error = = nil) {//parse data nsdictionary *dict = [Nsjsonserialization JSONObjectWithData:self.responseData Options:kniloptions Error:nil];
NSLog (@ "%@", dict);
}} @end
Notice
When the system time zone changes, a NSSYSTEMTIMEZONEDIDCHANGENOTIFICATION notification is issued to the Notification center, which then notifies the center to forward the notification to the appropriate observer.
MAIN.M registers the Bnrlogger instance as the Observer, and the system time zone settings change to receive the corresponding notification:
Add this line of code in the MAIN.M in the Secondary object method Application
[[Nsnotificationcenter defaultcenter]addobserver:logger selector: @selector ( Zonechange:) name:nssystemtimezonedidchangenotification Object:nil];
Implement this method in BNRLOGGER.M:
Add this line of code in the BNRLOGGER.M in the Secondary object method application
-(void) Zonechange: (nsnotification *) Note
{
NSLog (@ "The system Time zone has changed! ");
}
Block callback
MAIN.M the above "notification" method application in the following:
[[Nsnotificationcenter Defaultcenter]addobserver:logger selector: @selector (zonechange:) Name: Nssystemtimezonedidchangenotification Object:nil];
To
[[Nsnotificationcenter defaultcenter]addobserverforname:nssystemtimezonedidchangenotification Object:nil queue:[ Nsoperationqueue Mainqueue] usingblock:^ (nsnotification *note) {
NSLog (@ "The system time Zone has");
Bnrlogger.m This method in the notification method application is removed:
-(void) Zonechange: (nsnotification *) Note
{
NSLog (@ "The system time Zone has changed!");
}
Summarize
- For objects that do only one thing (for example), use a target-action pair.
- For more complex objects, such as nsurlsession, use a secondary object. The most common type of secondary object is the delegate object.
- Use notifications for objects (such as Nstimezone) that will trigger callbacks in multiple (other objects).
- The block implementation callback makes the code easier to read.
Thank you for reading, I hope to help you, thank you for your support for this site!