Is it possible to check if a particular method is being executed at a particular point of time on iOS ?
For example, I want to know if the method sampleMethod is being run at 1 minute after the app starts executing?
Can't you use _cmd for that?
NSLog(#"Method name = %#", NSStringFromSelector(_cmd));
Using breakpoints and/or the NSLog(NSString) function inside your mehthods.
Related
I using the below code to set elements in an array and return the array, the returned array is then passed to another method for more changes before again being returned.
NSMutableArray *returnArray = [[NSMutableArray alloc]init];
//call checkTP1
returnArray = [self checkTP1STD:addingTime :startToTP1 :TP1Result :nowDate :sevenHour :totalrest :returnArray];
//call check TP2
returnArray = [self checkTP2STD:addingTime :startToTP2 :TP2Result :nowDate :sevenHour :totalrest :returnArray :tp2Rest];
It is currently working as expected, my question is will it always wait for the checkTP1STD to return before executing checkTP2STD?
I have split the code into multiple methods to enable it to be more readable as i will be adding some other logic to pass different variable values to the methods,just wanted to make sure my basic idea will work.
In general: yes
Your question is curious, you seem to be concerned that checkTP1STD will return before checkTP2STD is called, but not that the calls to alloc and init will return before the call to checkTP1STD.
Are you actually intending to do asynchronous work in checkTP1STD (E.g. Using GCD or system framework methods which state they are async). If so the answer is still yes, but the call may return before all the work scheduled by checkTP1STD is complete - the very nature of asynchronous programming.
HTH
In short, yes. Code is executed in sequential order unless there's explicit calls to new threads, which you're not doing by the code you've given.
I was looking into iOS NUI Framework source code. I spotted the following line of codes but I couldn't figured out how it worked
- (void)override_didMoveToWindow
{
if (!self.isNUIApplied) {
[self applyNUI];
}
[self override_didMoveToWindow];
}
Just to be clear, they swizzled out the original implementation of DidMoveToWindow with this method in order to apply the class/style at run time. What confused me was that the function above never caused any infinite loop.
This may help: http://darkdust.net/writings/objective-c/method-swizzling
The swizzled method is actually exchanged with the original. So when the original method is called the swizzled method has already exchanged the implementation. And calling the "swizzled method" override_didMoveToWindow method will call the original function.
Comment the line
//[self override_didMoveToWindow];
works for me
It looks like not a loop because it appears the author assumes that [self applyNUI] always changes the state so that self.isNUIApplied becomes == YES
For example:
- (void)someFunc {
[self someFunc1];
[self someFunc2];
[self someFunc3];
}
I call someFunc. As I understand if I interrupt the application then the application doesn't guarantee that all the inner code in someFunc will be performed.
I must call someFunc1, someFunc2 and someFunc3 only once.
The problems I don't know how to solve:
someFunc1, someFunc2 and someFunc3 should be called atomically.
storing info for next launch. For example if we successfully have performed someFunc1 only then at next launch the application should call someFunc2 and someFunc3 only.
I know about method applicationWillTerminate:, but I don't know how to solve the current issue with it.
EDITED
Multitasking is not a solution because Even if the device is running iOS 4 or later, the device may not support multitasking., so it doesn't solve the general problem and makes the final solution more difficult only.
EDITED
For those who spam with off topic answers: read the title first - Save state when user exits an application. Where have you seen here putting the application into background?
This does't make sense. If these functions are running on the main thread, there is no way that the application can terminate normally while your functions are running. This is because the events sent like applicationWillTerminate: are sent on the same thread.
If your function is running on a different thread to the main thread, you will need to save some state information after each function completes, but you still have a race condition.
It might be better to check your application's state before running each function. For example, if you have a three step login/registration process with a server, you should query the server to see if the stage has been completed already before running it.
It's difficult to be more specific without knowing what you are doing in these functions.
You should use background tasks !
Take a look at the documentation here :
Executing a Finite-Length Task in the Background
Put the call of someFunc in the middle of the background task.
If your app goes to the background state, you'll have extra time to finish the execution of the method.
Make your functions to return bool, and when you call them, store the bool value to nsdefaults.
When the app restarts,check the bools from sndefaults, and if they are NO, run the functions and update them.
Nobody wants to help. So my temporary solution:
to save a last state I use a writing to a file because it enables to set its operation as atomic/nonatomic
I have replaced this code with something like this:
typedef enum {
state1,
state2,
state3
} MyState;
#property (assign) MyState state;
-(void)someFunc {
switch (state) {
case state1:
{
[self someFunc1];
state = state2;
[self someFunc];
break;
}
case state2:
{
[self someFunc2];
state = state3;
[self someFunc];
break;
}
default:
break;
}
}
I have a function call and some coding statements after the function. These statements should be called only after the function is executed completely How can it be achieved? Currently the statements are executed before the function is executed completely.
For example
NSInteger integerRestValue=[self buttonRestNameTag];
buttonRestNames.titleLabel.text=[[arrayGuessList objectAtIndex:integerRestValue]valueForKey:#"Name"];
Here the buttonRestNameTag function is called and before the execution is completed the buttonRestNames title label is set which cause it to crash.
How can this be resolved?
You may have initialized another Thread inside your function buttonRestNameTag.
Check that thing.
Or Try to use this function :
[self performSelectorOnMainThread:#selector(functionName) withObject:nil waitUntilDone:YES];
Hope this helps.
Edit for Kiron :
Make a variable in class and put returned value in that and access that variable.
This is helpful link to do this
iphone - performSelectorOnMainThread with return value
You can use GCD blocks
Try this.
In trying to implement the Google Analytics SDK for iOS, I've run into two brick walls.
The first one is that after executing this code in application:DidFinishLaunchingWithOptions:
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-XXXXXXX-YY"
dispatchPeriod:10
delegate:self];
[[GANTracker sharedTracker] setDebug:YES];
.. and then trying to track anything or call dispatch, no debug messages are logged whatsoever. I've added NSLog lines before and after tracking calls and the code is definitely being reached.
Secondly, when I do try and do a manual dispatch, it returns NO. All the other issues I've seen online are where dispatch returns YES but it's somehow not going through properly. What does one do if dispatch actually returns NO?
I've tried adding an NSError * reference to the track methods and those actually succeed (no error, function returns YES). But the events are definitely not being periodically dispatched, since we're seeing nothing on the GA account more than 24 hours later.
EDIT: I've also got NSLog calls in both of the delegate methods (hitDispatched: and trackerDispatchDidComplete:eventsDispatched:eventsFailedDispatch:), and neither of those are being called either.
i think you should check this to delegate method of GANTracker
- (void)trackerDispatchDidComplete:(GANTracker *)tracker
eventsDispatched:(NSUInteger)hitsDispatched
eventsFailedDispatch:(NSUInteger)hitsFailedDispatch{
//print or check number of events failed or success
}
//Delegate is set to 'nil' instead of class instance which implements the delegate methods.
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-XXXXXXX-YY"
dispatchPeriod:10
delegate:nil];
In your case, assuming that UIApplicationDelegate may be implementing GANTrackerDelegate, the message call should set delegate as ' self '.
Cheers!! Amar.
Possibly the dispatch is relying on the calling thread's run loop - Is it possible you are running this from a secondary thread, one which might not exist by the time the dispatch is suppose to call you back?
You've not enabled dryRun have you? Double check with:
[[GANTracker sharedTracker] setDryRun:NO];
Also try dispatchSynchronous, it'll block as it's sending but might help with if things aren't on the same threads:
[[GANTracker sharedTracker] dispatchSynchronous];
Just've checked it from scratch, dispatch perfectly worked meaning
a) your device is somehow different (i still have unsolved crashes on the particular iPad's 3 from Apple tester's unresolved, so it wouldn't be a huge surprise)
b) your code is somehow different - and that's much easier for you to fix.
For the a) there's no advice but to test it against all the devices you might get, for the b) i could only say what worked for me:
downloaded 1.4 SDK here
got Google sample projects with git clone https://code.google.com/p/google-mobile-dev.analytics-end-to-end/
configured final/AnalyticsSample to launch, changed the source slightly
(trackEvent::::: were called from sample, app was restarted manually as there's zero time period requiring dispatch call)
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[GANTracker sharedTracker] startTrackerWithAccountID:kGANAccountId
dispatchPeriod:0
delegate:self];
NSLog(#"Dispatch%#", [[GANTracker sharedTracker] dispatch] ? #"ed Successfully": #" Failed");
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
return YES;
}
That's it, log says Dispatched Successfully, worth trying i guess.
cough
I'd misspelled the #define to start the tracker object in my app delegate. Other files were spelled correctly, hence the logging statements showing up, but when I tried to log just before the tracker was started it didn't show.
Oops. Well, at least there's a decent troubleshooting post for Google Analytics on SO now!