Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 01-11-2011, 10:24 AM   #1 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default Memory Problem iPad 4.2

Hello, I had made an app for iPad that uses an UIScrollView to load some views, each one with different XIB file.
When I used the iOS 3.2 i donīt have any problem, when I released a view I test in Instruments that it deallocated the memory. BUT when I compiled in iOS 4.2 it doesnt deallocate the memory, and after load 10 pages it crashed. I think that release method doesnīt work.

Any idea?


// unload the pages which are no longer visible
for (int i = 0; i < [scrollViewPages count]; i++)
{
//UIView *viewController = [scrollViewPages objectAtIndex:i];

Articulo1 *viewController=[scrollViewPages objectAtIndex:i];
if((NSNull *)viewController != [NSNull null])
{
if(i < currentPage || i > currentPage)
{
[viewController.view removeFromSuperview];
[viewController viewDidUnload];
[scrollViewPages replaceObjectAtIndex:i withObject:[NSNull null]];

viewController=nil;
[viewController release];


}
}


Other .m

- (void)viewDidUnload {
player=nil;

NSLog(@"viewDidUnload Articulo1");


[scrollView1 release];
[scrollView2 release];
[scrollView3 release];
[Parrafo1 release];
[Parrafo2 release];
[Parrafo3 release];
[Parrafo4 release];
[Parrafo5 release];
[Parrafo6 release];
[Parrafo7 release];
[Parrafo8 release];

[Portada release];
[Pagina1 release];
[Pagina2 release];
[Pagina3 release];
[Pagina4 release];
[Pagina5 release];
[botoninfo1 release];
[botoninfo2 release];
[botonInternet1 release];
[botonInternet2 release];
[botonInternet3 release];
[botonInternet4 release];
[botonInternet5 release];
[botonInternet6 release];
[paginas release];
[articulo release];
}


I noticed that when it has a memory warning level 1 it deallocated the memory, but almost ever it crashed.
joshscofield is offline   Reply With Quote
Old 01-11-2011, 10:39 AM   #2 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Really not much reason to call this yourself:

Code:
[viewController viewDidUnload];
This is backwards. It was a problem on 3.2 as well, so you must have just been lucky.

Code:
viewController=nil;
[viewController release];
I think you are confused about the role of viewDidUnload vs. the role of dealloc.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 11:10 AM   #3 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Really not much reason to call this yourself:

Code:
[viewController viewDidUnload];
This is backwards. It was a problem on 3.2 as well, so you must have just been lucky.

Code:
viewController=nil;
[viewController release];
I think you are confused about the role of viewDidUnload vs. the role of dealloc.
Thanks, iīll try to read more about it.
Any idea to solve the problem? Thanks
joshscofield is offline   Reply With Quote
Old 01-11-2011, 11:12 AM   #4 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Code:
viewController=nil;
viewController is now nil. So that means this:

Code:
[viewController release];
...is the same thing as doing this:

Code:
[nil release];
What do you expect that to do?
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 11:39 AM   #5 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Code:
viewController=nil;
viewController is now nil. So that means this:

Code:
[viewController release];
...is the same thing as doing this:

Code:
[nil release];
What do you expect that to do?
I have a NSMutableArray of ViewControllers (Articulo1 class) so I want to release that ViewControllers in order to load others ViewControllers. When I load 10 or 11 the app crashed becouse it doesnīt free the memory.
I dont know why, but in 3.2 it works.

so, in Articulo1.m I want to release all the IBOutlets:


- (void)dealloc {
NSLog(@"dealloc Articulo1");
[scrollView1 release];
[scrollView2 release];
[scrollView3 release];
[Parrafo1 release];
[Parrafo2 release];
[Parrafo3 release];
[Parrafo4 release];
[Parrafo5 release];
[Parrafo6 release];
[Parrafo7 release];
[Parrafo8 release];

[Portada release];
[Pagina1 release];
[Pagina2 release];
[Pagina3 release];
[Pagina4 release];
[Pagina5 release];
[botoninfo1 release];
[botoninfo2 release];
[botonInternet1 release];
[botonInternet2 release];
[botonInternet3 release];
[botonInternet4 release];
[botonInternet5 release];
[botonInternet6 release];
[paginas release];
// [articulo release];
[super dealloc];
}



- (void)viewDidUnload {

player=nil;

NSLog(@"viewDidUnload Articulo1");



self.scrollView1=nil;
self.scrollView2 =nil;
self.scrollView3 =nil;
self.Parrafo1 =nil;
self.Parrafo2 =nil;
self.Parrafo3 =nil;
self.Parrafo4 =nil;
self.Parrafo5 =nil;
self.Parrafo6 =nil;
self.Parrafo7 =nil;
self.Parrafo8 =nil;


self.Portada =nil;
self.Pagina1 =nil;
self.Pagina2 =nil;
self.Pagina3 =nil;
self.Pagina4 =nil;
self.Pagina5 =nil;
self.botoninfo1 =nil;
self.botoninfo2 =nil;
self.botonInternet1 =nil;
self.botonInternet2 =nil;
self.botonInternet3 =nil;
self.botonInternet4 =nil;
self.botonInternet5 =nil;
self.botonInternet6 =nil;
self.paginas =nil;

// [super viewDidUnload];

}

in superclass.m i have the array and want to remove the viewcontrollers:

for (int i = 0; i < [scrollViewPages count]; i++)
{
//UIView *viewController = [scrollViewPages objectAtIndex:i];

Articulo1 *viewController=[scrollViewPages objectAtIndex:i];
if((NSNull *)viewController != [NSNull null])
{
if(i < currentPage-1 || i > currentPage+1)
{
//[viewController removeFromSuperview];
//[scrollViewPages replaceObjectAtIndex:i withObject:[NSNull null]];
//[viewController viewDidUnload];

[viewController.view removeFromSuperview];
// [viewController viewDidUnload];
//viewController=nil;
[viewController release];
//[sum release];
[scrollViewPages replaceObjectAtIndex:i withObject:[NSNull null]];
// [scrollView1.subviews replaceObjectAtIndex:i withObject:[NSNull null]];
// viewController=nil;
// [viewController release];
cargadas--;

}
}
}

I think im confusing whit that becouse it works in 3.2 ...
joshscofield is offline   Reply With Quote
Old 01-11-2011, 11:44 AM   #6 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Don't provide additional information until I ask for it. Answer the question that I actually did ask. You need to understand this stuff, so focus on the question at hand.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 11:47 AM   #7 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Code:
viewController=nil;
viewController is now nil. So that means this:

Code:
[viewController release];
...is the same thing as doing this:

Code:
[nil release];
What do you expect that to do?
I want to delete the viewController object and release the memory that itīs using.
joshscofield is offline   Reply With Quote
Old 01-11-2011, 11:49 AM   #8 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

I understand what your goal is.

I'm asking you to take a look at your code, and figure out how that either succeeds or fails at accomplishing your goal.

I know what you want to do. Can you explain to me what that code actually does?
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 11:55 AM   #9 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
I understand what your goal is.

I'm asking you to take a look at your code, and figure out how that either succeeds or fails at accomplishing your goal.

I know what you want to do. Can you explain to me what that code actually does?
That code actually removes the controllerview from the scrollview, so it dissapear ( the view). but if i saw in Instruments, it doesnīt release the real memory, so it is increasing until it crashed when i load other views
joshscofield is offline   Reply With Quote
Old 01-11-2011, 11:57 AM   #10 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Just these two lines:

Code:
viewController=nil;
[viewController release];
What does this do? Not what do you think it does, or what you hope it does. What does it actually do?
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 11:59 AM   #11 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Just these two lines:

Code:
viewController=nil;
[viewController release];
What does this do? Not what do you think it does, or what you hope it does. What does it actually do?
Oh, i think actually doesnīt do nothing. Iīm lost.
joshscofield is offline   Reply With Quote
Old 01-11-2011, 12:01 PM   #12 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Well, actually you're right. It doesn't do anything. More specifically, it doesn't release the view controller. Can you explain why not?
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-11-2011, 12:04 PM   #13 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Well, actually you're right. It doesn't do anything. More specifically, it doesn't release the view controller. Can you explain why not?
I understand that viewcontroller=nil; is a mistake. I delete that line, but the code is doing the same.
joshscofield is offline   Reply With Quote
Old 01-11-2011, 12:11 PM   #14 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

The line is fine, but it should be AFTER the release line. Not before.

Your viewDidUnload should only contain the following items:
1. IBOutlets ([self setWhatever:nil])
2. Anything you re/build in viewDidLoad

You should not call viewDidUnload yourself. Your viewDidUnload should call [super viewDidUnload];

dealloc should release all retain and copy properties.

Make these adjustments, and then see where things stand. Use the CODE tags for posting code. Remove any commented code from your post, as it just makes things confusing.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-12-2011, 11:23 AM   #15 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
The line is fine, but it should be AFTER the release line. Not before.

Your viewDidUnload should only contain the following items:
1. IBOutlets ([self setWhatever:nil])
2. Anything you re/build in viewDidLoad

You should not call viewDidUnload yourself. Your viewDidUnload should call [super viewDidUnload];

dealloc should release all retain and copy properties.

Make these adjustments, and then see where things stand. Use the CODE tags for posting code. Remove any commented code from your post, as it just makes things confusing.
Thanks, Iīve done that adjustment but it stills doing the same. My code is better now, but nothing has changed. If I install in ios 3.2 it releases and free the real memory, but if I install in ios 4.2 it doesnīt deallocate the real memory, so it grow up until 150 Mb and then crash the app.
Is there any change between memory management in those iOS? It may be important, but when I send a Memory Warning in the simulator, it deallocated the real memory, so maybe I want to do the same that do the memory Warning.
joshscofield is offline   Reply With Quote
Old 01-12-2011, 11:35 AM   #16 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

No, memory management has been the same for a very long time. I honestly don't see how your original code worked correctly in OS 3.2. You were leaking a view controller every single time.

Are you sure the view controllers are dying? Have you put logs in dealloc to make sure it is being called?

Post the current version of your code (remove any commented lines). Use the CODE tags (# button).
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-12-2011, 11:55 AM   #17 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 9
joshscofield is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
No, memory management has been the same for a very long time. I honestly don't see how your original code worked correctly in OS 3.2. You were leaking a view controller every single time.

Are you sure the view controllers are dying? Have you put logs in dealloc to make sure it is being called?

Post the current version of your code (remove any commented lines). Use the CODE tags (# button).
My code:

Where I create the viewcontroller (Articulo1) and add into ScrollvViewPages Array. Also I add into ScrollView1 Subview.

Code:
 sum =[[Articulo1 alloc] initWithNibName:nombre bundle:[NSBundle mainBundle]];
			sum.scrollViewPrincipal= scrollView1;
			sum.ViajarSuper=Flechas;
			sum.FlechaIzq=FlechaIzq;
		}
		
		sum.controller=self.navigationController;
		
		sum.articulo=a;
		Indice=sum.view;
		CGRect rect2=Indice.frame;
		
		rect2.size.height = kScrollObjHeight;
		rect2.size.width = kScrollObjWidth;
		rect2.origin.x = 0;
		rect2.origin.y = rect2.size.height *page;
		if(horizontal){
			if(([sum class]==[Articulo1 class]) || ([sum class]==[Hoteles class]))
				[sum layoutScrollImagesHorizontal];
			rect2.size.height = kScrollObjHeight*1.33;
			rect2.size.width = kScrollObjWidth*1.33;
			rect2.origin.x = 0;
			rect2.origin.y = rect2.size.height * page;
		}
		Indice.frame=rect2;
		Indice.tag=99+page;
		sum.view=Indice;
		[scrollViewPages replaceObjectAtIndex:page withObject:sum];

		
		[scrollView1 addSubview:Indice];
		cargadas++;
		[sum release];
		sum=nil;
		Indice=nil;
The code where I want to unload the viewcontroller:

Code:
    // Releases the view if it doesn't have a superview.
	Portada=NULL;
	Editorial_1=NULL;
	Indice=NULL;
	
	// Calculate the current page in scroll view
	CGPoint	p = scrollView1.contentOffset;

	CGPoint contentoffset= [scrollView1 contentOffset];
	double content= contentoffset.y;
	
	int page= p.y/1004;
	if(horizontal)
		page=p.y/(1004*1.33);
	
    int currentPage = page;
	
	// unload the pages which are no longer visible
	for (int i = 0; i < [scrollViewPages count]; i++) 
	{
	
		
	Articulo1 *viewController=[scrollViewPages objectAtIndex:i];
        if((NSNull *)viewController != [NSNull null])
		{
			 if(i < currentPage-1 || i > currentPage+1)
		
			{
				
				[viewController.view removeFromSuperview];

				
				[scrollViewPages replaceObjectAtIndex:i withObject:[NSNull null]];
				//If i put here [viewController release] it crash!!
				cargadas--;
				
			}
			
			
		}

		
		
	}

The code into Articulo1.m (what i want to deallocate)

Code:
- (void)dealloc {
	NSLog(@"dealloc Articulo1");
	  

	
	
	[Parrafo1 release];
	[Parrafo2 release];
	[Parrafo3 release];
	[Parrafo4 release];
	[Parrafo5 release];
[Parrafo6 release];
	[Parrafo7 release];
	[Parrafo8 release];
	NSLog(@"Los parrafos dealloc Articulo1");
	[Portada release];
	[Pagina1 release];
	[Pagina2 release];
	[Pagina3 release];
	[Pagina4 release];
	[Pagina5 release];
	NSLog(@"Las paginas dealloc Articulo1");
	[botoninfo1 release];
	[botoninfo2 release];
	[botonInternet1 release];
	[botonInternet2 release];
	[botonInternet3 release];
	[botonInternet4 release];
	[botonInternet5 release];
	[botonInternet6 release];
	NSLog(@"Los botones dealloc Articulo1");
	[paginas release];
	NSLog(@"el numero de paginas");
//	[articulo release];	
	
	[scrollView1 release];
	[scrollView2 release];
	[scrollView3 release];
	NSLog(@"los scrollviews dealloc Articulo1");
	[super dealloc];
	NSLog(@"el super dealloc Articulo1");



	
}


- (void)viewDidUnload {

	[super viewDidUnload];
	
	
	[super viewDidUnload];
	NSLog(@"viewDidUnload Articulo1");
	scrollView1=nil;
	scrollView2 =nil;
	 scrollView3=nil;
	
	
	
	Parrafo1 =nil;
	Parrafo2 =nil;
	Parrafo3 =nil;
	Parrafo4 =nil;
	Parrafo5 =nil;
	Parrafo6 =nil;
	Parrafo7 =nil;
	Parrafo8 =nil;
		
	botoninfo1 =nil;
	botoninfo2 =nil;
	
botonInternet1 =nil;
	botonInternet2 =nil;
	botonInternet3=nil;
	botonInternet4 =nil;
	botonInternet5 =nil;
	botonInternet6 =nil;
	paginas =nil;
	
}
The dealloc function is called, because the nslogs on the console demostrated it. But ViewDidUnload is never called.
joshscofield is offline   Reply With Quote
Old 01-12-2011, 12:57 PM   #18 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

viewDidUnload won't be called unless the system unloads the view, which normally won't happen until it needs memory. So it is not at all strange that viewDidUnload is not called. It's a good thing it isn't, because you are using it wrong. You need to use the setter to nil out the properties.

Things I notice that are weird:

Code:
sum = [[Articulo1 alloc] initWithNibName:nombre bundle:[NSBundle mainBundle]];
Why isn't sum a new variable right here? Is it a property? If so, why?

Code:
sum.scrollViewPrincipal= scrollView1;
...
[scrollView1 addSubview:Indice];
So, scrollView1 is the scroll view that you are adding views to, so why do you give it to the view controllers? I don't see where you are releasing scrollViewPrincipal.

Code:
Indice=sum.view;
...
sum.view=Indice;
This doesn't actually do anything. You don't seem to need Indice. If there is a reason that I don't see, then it should be a local variable, not a property.

--

If dealloc is being called, then the view controller is dying. If you are still leaking memory, then either you are not releasing everything properly in dealloc, or you are making errors elsewhere in your code.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Reply

Bookmarks

Tags
crash, ios 42, memory, release

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 364
9 members and 355 guests
7twenty7, blueorb, iAppDeveloper, iGamesDev, Mah6447, Morrisone, mottdog, sacha1996, Touchmint
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,667
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, host number one
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:35 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0