I'm a beginner in the program.
I would like to call the getFlag method in viewDidLoad, retrieve information from the server asynchronously, and use the value in viewWillAppear, but the code below sets the value to isFlag.
The timing is slow and the viewWillAppear does not run in time.
What should I do in this case?
@interfacehogeViewController(){
BOOL isFlag;
}
- (void) viewDidLoad{
superviewDidLoad;
self getFlag;
}
-(void)viewWillAppear:(BOOL)animated{
super viewWillAppear: animated;
if(isFlag){
...
} else {
...
}
}
-(void)getFlag{
NSUserDefaults* defaults = NSUserDefaults standardUserDefaults;
NSSstring* serverInfo_=nil;
serverInfo_= [NSString stringWithFormat:@"https://%@", WebServerInfo];
NSSstring*mediaApi=[serverInfo_stringByAppendingFormat:@"/api/hoge/";
NSURL*url_= NSURL URLWithString: mediaApi;
[request setHTTPMethod:@"GET";
NSURLConnection sendAsynchronousRequest:request
queue —NSOperationQueue mainQueue
completionHandler:^(NSURLResponse*response, NSData*data, NSError*error){
if(data){
isFlag = true;
}
}];
}
Hello!
I think the wrong approach is to use asynchronous, i.e., data in viewWillAppear
that you don't know when to return.As you know, viewWillAppear
is a method called just before the view is displayed, so it doesn't wait for getFlag to finish.
If you really want to use viewWillAppear
, I think you have no choice but to synchronize instead of asynchronous!
Nice to meet you.Like Kosuke Ogawa, I think it would be desirable to complete data retrieval before displaying hogeView
, but sometimes hogeView
is the first view
that the application started.
So, I thought about two ways to change the behavior with the value from the server without changing the current source as much as possible.
This can be done by modifying -(void)getFlag
and
- (void) getFlag
{
NSSstring* serverInfo_=nil;
serverInfo_= [NSString stringWithFormat:@"https://%@", WebServerInfo];
NSSstring*mediaApi=[serverInfo_stringByAppendingFormat:@"/api/hoge/";
NSURL*url_= NSURL URLWithString: mediaApi;
NSData*data=[NSDataDataWithContentsOfURL:url];
if(data)
{
// Data is not empty
}
else
{
// When data is empty
}// end if data
}// end-(void)getFlag
This is the first method, but the waiting time is the same, so let's get used to asynchronous transfer.
Of course, it's more troublesome than the former.
First, prepare a flag for the member variable to indicate whether the transfer is complete and initialize it.
@interfacehogeViewController(){
BOOL isFlag;
BOOL getDataDone;// Flag to wait for transfer completion
}
- (void) viewDidLoad{
superviewDidLoad;
getDataDone=NO;// Initialize transfer completion flag before retrieving data
self getFlag;
}
Next, set this flag when the asynchronous completion handler completes data retrieval.
[NSURLConnection sendAsynchronousRequest:request]
queue —NSOperationQueue mainQueue
completionHandler:^(NSURLResponse*response, NSData*data, NSError*error){
if(data){
isFlag = true;
}
getDataDone=YES; // Flag Transfer Completion at the End of the Completion Handler
}];
Then wait for the completion handler to finish in viewWillAppear
-(void)viewWillAppear:(BOOL)animated{
super viewWillAppear: animated;
// The process of waiting for the transfer to complete.
while(!getDataDone)
{
NSThread sleepTimeInterval:0.1;
} // end while getDataDone become true
// If getDataDone is YES, proceed to the next line.
if(isFlag){
...
} else {
...
}
}
I'm sorry, but I haven't checked the operation, so please add a __block
declaration to the variable if necessary
573 rails db:create error: Could not find mysql2-0.5.4 in any of the sources
917 When building Fast API+Uvicorn environment with PyInstaller, console=False results in an error
574 Who developed the "avformat-59.dll" that comes with FFmpeg?
613 GDB gets version error when attempting to debug with the Presense SDK (IDE)
© 2024 OneMinuteCode. All rights reserved.