What is the lifetime of a PhoneGap plugin? - plugins

Is there something I need to take into account about the plugin instance lifetime, or can I assume that this object exists all the time my web view is visible?
It seems from looking at a few plugins, some people tend to use some kind of singleton manager to store data in their PhoneGap plugins. Why not just store it in the PhoneGap plugin itself?
The reason for asking is that it seems the only proper way to communicate with the web view is through the [self writeJavaScript:message] method. If I register myself to receive some notification, I want to be sure my plugin instance exist.

The plugin lives as long as the web view is alive.
The proper way to initialize variables or register for callbacks is in the
- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView {
self = [super initWithWebView:theWebView];
if (self) {
_variable = [[Variable alloc] init];
[Classname addListener:self];
}
return self;
}
method. That method is run for all plugins.
Don't forget to clean up after yourself in the dealloc method.

Related

Random crashes occur in my iphone project, see two call stacks, all in web core, all crash after UIWebView deallocate

Random crashes occur in my iphone project, see two call stacks, all in web core, all crash after UIWebView deallocate.
See crash 1, seems web core can't close it completely, is it blocked by other running threads?
See crash 2, why it is still dealing with some issues even if UIWebView has been released?
Any idea or discussion will be appreciated, thanks in advance.
Crash 2 has higher reproducible rate than crash 1, scan WebCore source code, it seems be manifest cache has been deleted (who did it?) when try to access it.
My guess is that you're setting some object (probably your view controller) as the delegate of your webView, either via Interface Builder, or via code that looks something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.webView.delegate = self;
}
- (void)dealloc
{
[self.webView release];
[super dealloc];
}
This code has a serious bug that's not immediately obvious if you don't know what to look for. Can you spot it?
When the controller gets dealloc'd it releases the webView, but this doesn't necessarily mean the web view no longer exists. It may still be retained by some code down inside its internal implementation, and it may still be loading content.
When it finishes loading, the web view will call a method like webViewDidFinishLoad: on its delegate. The problem is, your view controller was the delegate, and your view controller no longer exists. The section of memory where your view controller used to live has been reclaimed by the operating system, and is no longer accessible to your application process. The web view doesn't know this though. It still has a reference to that memory address in its delegate property. So it tries to call a delegate method on that object, and whoops... EXC_BAD_ACCESS.
Crashes like this appear to be random since they depend on what your app is doing in the background at the time. This makes them tricky to diagnose. Fortunately they're easy to solve. Simply set the object's delegate to nil before you release it your dealloc statement, like this:
- (void)dealloc
{
self.webView.delegate = nil;
[self.webView release];
[super dealloc];
}
By setting the web view's delegate to nil before you release it, you guarantee that the web view won't try to call delegate methods on your object after it's been deallocated.
If you're using ARC, your class may not have a dealloc method. That's normally fine, but in a case like this you should go ahead and add one. You don't want to call release if you're using ARC, but you should still add a dealloc method and set the delegate property to nil.
To avoid similar crashes in the future, apply this best practice any time you set your object as the delegate of another object.
Before releasing the webview, try to reset the delegate an stop loading.
[webView stopLoading];
webView.delegate = nil;
[webView release];
webView = nil;

iphone,how to create NSOperationQueue

I've got a couple background tasks to process while still keeping the UI responsive. I started down the path of creating and managing threads, but soon came across the NSOperations. Sounds like a better solution . . .
However, I cannot seem to get a reference to the NSOperationQueue. The Threading Programming Guide suggests the following
#implementation MyCustomClass
- (void)launchTaskWithData:(id)data
{
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:#selector(myTaskMethod:) object:data];
// Add the operation to the internal operation queue managed by the application delegate.
[[MyAppDelegate sharedOperationQueue] addOperation:theOp];
}
// This is the method that does the actual work of the task.
- (void)myTaskMethod:(id)data
{
// Perform the task.
}
. . . but I (and more importantly, the compiler) don't see the 'sharedOperationQueue' message when I implement the code in my app.
What am I missing?? Is sharedOperationQueue deprecated and no longer available? How can I get an NSOperationQueue reference?
sharedOperationQueue is not part of the official API. It is a custom method you are supposed to implement yourself, in this example as a class method in your app delegate class. The method should create and return NSOperationQueue or, if it already has created the queue, simply return the existing one.
How you implement this in your case is up to you. You don't have to follow the example. Simple create an operation queue with alloc/init (no magic here) and store a reference to it in a property so that you can later release it when you no longer need it.
Cocoa Is My Girlfriend has a good tutorial, this will help you to use NSOperationQueue.
You have to declare application delegate before adding operation:
AppDelegateClass * MyAppDelegate = [NSApp delegate];

Memory leaking problem in iphone app

i created one method like below one:
+ (JSONManager *)GetInstance
{
if (!instance)
{
instance = [[JSONManager alloc] init];
}
return instance;
}
and i need to use same method in different view...if i release this one for the first view it is working fine and if trying to navigate to second view my app is crashing.
can any one please let me know where do i need to release that object
Thanks in advance
This appears to be a singleton. You should not be releasing it in the first view. You will want to use the same instance throughout the lifetime of the application.
If that is not the requirement, you should provide the mechanism to set the instance variable to nil as it will be pointing to a deallocated object once you release it. But I think this is not the case.
If you want a true singleton use this template and generate it.
It's based on Apple's Singleton code
http://blog.mugunthkumar.com/coding/objective-c-singleton-template-for-xcode-4/
The code looks like a Singleton. The purpose of Singleton is to have a single instance of a resource available throughout an app.
So, you should not release the instance, after you are done with it in the first view, since you want to use it in another view.
If you are worried about releasing this instance have a look at the following link for a template singleton class for an iOS application:
http://www.galloway.me.uk/tutorials/singleton-classes/

iOS-FBConnect - requests results crash the app if the delegate of them released

I'm developing an iOS app and views create a request for their data,
now if the user dismiss the view, it's released and when the FBConnect call:
if ([_delegate respondsToSelector:
#selector(request:didReceiveResponse:)]) {
[_delegate request:self didReceiveResponse:httpResponse];
}
the app is crashed...
Any solution for that case?
Thanks!
Try using a higher-level controller as delegate, e.g. the main view controller, or the app delegate itself. This way you will always be sure that that component will not be released while the app is running.
either retain the _delegate. Or release the caller (the one making requests) as well from _delegate's dealloc method.
Or if both the above solutions are not suitable, then put the protocol implementation somewhere else.If you post more details may be then people will be able to provide specific answer.

iPhone proper usage of Application Delegate

I'm looking to be able to reference certain state/objects through anywhere in my application. For instance, a user logs in to their application, I need to call a web service and retrieve the users information. Then I want to be able to access this information from anywhere in the application with something like the following:
myAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
user = delegate.u;
Is setting an instance variable as a User object in the app delegate and referencing it from there when needed a poor way of going about it? I typically set it there upon the user's login.
Wanted to hear how the pros handle this one.
Normally, you should only connect things to the app delegate if they:
Were created from the same NIB file as the app delegate (i.e. static UI elements in single window interfaces)
Are associated with application-level event handling that passes through the app delegate (like the menu item for the Preferences Window)
For everything else, you should create a singleton which manages access to them.
Jason Coco suggested routing through the Application Controller. In my programs I normally avoid this, as I think it puts too much responsibility at the top level -- I think things should self-manage where possible and that higher level management should only be used when there is a requirement for coordination between peer-level modules.
I'm not going link my own blog but if you Google me and singletons you'll probably find a post I wrote going into more detail.
Matt is a bit too modest. His posting on the subject is one of the best I have read, and deserves a link. http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
I don't see any problem with your approach. I usually use a singleton to handle this situation:
// MyCommon.h:
#interface MyCommon
class MyCommon : NSObject
{
int user;
};
#property(assign) int user;
+ (MyCommon *)singleton;
#end
// MyCommon.m:
#implementation MyCommon
static MyCommon * MyCommon_Singleton = nil;
+ (MyCommon *)singleton
{
if (nil == MyCommon_Singleton)
{
MyCommon_Singleton = [[MyCommon_Singleton alloc] init];
}
return MyCommon_Singleton;
}
#end
The MyCommon singleton is then used anywhere in my application as follows:
int user = [MyCommon singleton].user;
Usually you would ask your application's controller for this information and it would be responsible for knowing how to store it/look it up in whatever data model exists. Your application's controller may or may not be the same as the applications delegate (in most simple applications, it is the same).