4

I have a small app with iAds, and allow people to pay to upgrade.

The iAd is setup in the application's NIB. I check the purchase status in the viewDidLoad method of the main UIViewController, and call the following methods on the ADBannerView outlet member:

[adBanner removeFromSuperview];
adBanner = nil;

Unfortunately if I watch the device's data usage, some data is still downloaded for the Ad.

Is there any way to properly kill the iAd so it doesn't load any data?

I know I could create the iAd view programatically and then add it only if the user has not purchased the product, but my product is working nicely from the NIB and I'd rather not change it for this reason.

UPDATE:

In my .h file I have:

IBOutlet ADBannerView* adBanner;

In the .m file in - (void)viewDidLoad method I have:

if (purchased) {
    [adBanner removeFromSuperview];
    adBanner.delegate = nil;
    adBanner = nil;
}

I would hope this would be enough to remove the iAd before it gets a chance to download any data.

Alas, this isn't enough to prevent the view from downloading data. I suspect there is a delay in it being fully dealloc'd at that time – but I don't know how to do this, short of calling dealloc itself.

Does anyone know of a better/correct way to completely destroy an object loaded via the XIB and assigned to an IBOutlet?

William Denniss
  • 16,089
  • 7
  • 81
  • 124
  • Incidentally, it was using about 19KB up and 79KB down of data. Not much, but still a waste, and bad since this app can be used in situations where this could be a problem (e.g. a 1G connection in a forest...) – William Denniss May 11 '11 at 08:20

4 Answers4

4

I suspect you don't completely release the ad banner.

Did you autorelease the adBanner when creating it? If you didn't, the code you are showing here doesn't properly release the banner.

Most likely, you didn't autorelease it and it's retained. What you need to do is:

[adBanner release]; 

instead of

adBanner = nil;

which is by the way useless since it only sets the pointer adBanner to nil but doesn't release the object at all.

Kamchatka
  • 3,597
  • 4
  • 38
  • 69
  • 1
    The problem is that the `adBanner` object is being created and set to my IBOutlet by the NIB process. I've updated my question with my code – as you can see I never retain that object. Basically, i'm trying to destroy the object in the `viewDidLoad` method but it seems I'm not destroying it correctly (or perhaps fast enough) as it still consumes data. One solution could be to just create it programmatically in the first place – but my code is working with the XIB so I'm just wondering if there is a way to get it working the "interface builder" way. – William Denniss May 31 '11 at 11:28
  • You're probably right that it's "not being completely released" which causes this problem. Any idea how I can trick the NIB process to make it properly released & destroyed? – William Denniss May 31 '11 at 11:34
  • 3
    You should be able to simply release the adBanner after you deactivate it (make sure to nullify the delegate), even if it has been created in the XIB. However I would just create the banner by hand. If you use it in a standard way, the code should be very similar to http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/iAd_Guide/BannerAdvertisements/BannerAdvertisements.html. – Kamchatka May 31 '11 at 13:13
  • Thanks I think I'll go with adding it in code as you suggest. Was hoping there was an option to do this the "XIB way", but it seems there is not. – William Denniss Jun 06 '11 at 16:37
  • How do you release the banner with ARC? – AdamT May 12 '15 at 08:23
1

I think you'll have to use a second nib, without the iAd banner. The nib loading process will instantiate all elements of the nib before passing control back to your objects. That's why you can't stop the iAd from trying to load an ad.

First, duplicate the current nib, and just delete the iAd banner view. Then override the view controller's initWithNibName:bundle: method to check for paid status. If paid, change the nib name to the non iAd nib, and call the superclass's method with the other nib.

Mr. Berna
  • 10,525
  • 1
  • 39
  • 42
  • Thanks for the suggestion. I think given the choice of 2 XIBs or adding it in code conditionally, I'll take the latter. Perhaps for others it will be different. – William Denniss Jun 06 '11 at 16:36
0

You could set the adBanner.delegate = nil also, to stop the adBanner from communicating with it's delegate.

Tuyen Nguyen
  • 4,389
  • 7
  • 51
  • 77
0

@mr-berna is right in that you need to conditionally load the iAd view. You can either do as he suggests and use a second nib or create the iAd view programmatically.

ThomasW
  • 16,981
  • 4
  • 79
  • 106