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 11-18-2011, 05:12 AM   #1 (permalink)
Token farm animal
 
sneaky's Avatar
 
Join Date: Apr 2011
Posts: 321
sneaky is on a distinguished road
Default Thread safe access of subviews?

In my app I have some core plot views that changes every now and then. The call to change is initiated by whatever thread just parsed the xml data that just came in. As I have a few of these plots on the screen that are listening to different notifications and sometimes the same notification I think this is where I have the problem.

This code here:
Code:
for (UIView *view in [self subviews]) {
		if ([view isKindOfClass:[CPTGraphHostingView class]]) { // <<<<<
			if (view.tag == _hostingTag) {
				[view removeFromSuperview];
			}
		}
	}

*** -[ isKindOfClass:]: message sent to deallocated instance 0x234430

In this kind of scenario, how can I make sure that I'm not accessing a view that has been deallocated already, presumably by some other thread?
sneaky is offline   Reply With Quote
Old 11-18-2011, 05:22 AM   #2 (permalink)
Registered Member
 
Naughty_Ottsel's Avatar
 
Join Date: Aug 2008
Location: Gillingham, Dorset, UK
Age: 19
Posts: 218
Naughty_Ottsel is on a distinguished road
Send a message via MSN to Naughty_Ottsel
Default

All UIKit objects must be accessed on the main thread so in the case of what you're doing it should be along the lines of:

Code:
for (UIView *view in [self subviews]) {
		if ([view isKindOfClass:[CPTGraphHostingView class]]) { // <<<<<
			if (view.tag == _hostingTag) {
				[self performSelectorOnMainThread:@selector(removeFromSupeview) withObject:view waitUntilDone:YES]; 
			}
		}
	}
Don't quote that code exactly as I haven't tested it, but it should work, hopefully
__________________
Follow me on Twitter
Naughty_Ottsel is offline   Reply With Quote
Old 11-18-2011, 05:44 AM   #3 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 46
kasparp is on a distinguished road
Default

You should not be doing GUI updates in another thread.

You should defer it to mainthread like Naighty_Ottsel suggest, maybe even a bit more I dont even like the playing with UIView and [self subviews] in another thread.

Imo. fetch the Xml, parse it and get it onto your main thread and do your gui updates there.
__________________
Cheers
kasparp is offline   Reply With Quote
Old 11-18-2011, 05:57 AM   #4 (permalink)
Token farm animal
 
sneaky's Avatar
 
Join Date: Apr 2011
Posts: 321
sneaky is on a distinguished road
Default

I've changed so I'm passing the notification now on the main thread. this I hope should work around the problem.
sneaky is offline   Reply With Quote
Old 11-18-2011, 07:54 AM   #5 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by Naughty_Ottsel View Post
All UIKit objects must be accessed on the main thread so in the case of what you're doing it should be along the lines of:

Code:
for (UIView *view in [self subviews]) {
		if ([view isKindOfClass:[CPTGraphHostingView class]]) { // <<<<<
			if (view.tag == _hostingTag) {
				[self performSelectorOnMainThread:@selector(removeFromSupeview) withObject:view waitUntilDone:YES]; 
			}
		}
	}
Don't quote that code exactly as I haven't tested it, but it should work, hopefully
That's the right idea, but the code isn't quite right.

The code:

Code:
[view removeFromSuperview];
is sending the message removeFromSuperView to the object "view."

Thus, to send that message to the main thread, it should be rewritten as:

Code:
[view performSelectorOnMainThread: @selector(removeFromSupeview) 
  withObject: nil 
  waitUntilDone: NO]; [/b]
The waitUntilDone parameter would only need to be TRUE if the worker thread goes on to do other things that depend on the view having been removed.
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 11-18-2011, 08:22 AM   #6 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 46
kasparp is on a distinguished road
Default

I still think moving the entire gui update to main thread, as I think he did, is a better option that for loop in another thread is asking for trouble.

What happens to the for loop, when [self subviews] array is modified by main or another thread?

What happens if
if ([view isKindOfClass:[CPTGraphHostingView class]]) {
return YES
and for some reason 2 requests got started or maybe the main thread got some input and decided to remove/deallocate the view on its own, now when our thread gets to removeFromSubview it was already deallocated....
__________________
Cheers
kasparp is offline   Reply With Quote
Old 11-18-2011, 08:57 AM   #7 (permalink)
Token farm animal
 
sneaky's Avatar
 
Join Date: Apr 2011
Posts: 321
sneaky is on a distinguished road
Default

The problem here was coming from 2 sources I think.
1) I shouldn't be playing with the GUI in a background thread. I'm passing the notification on the main thread now so the entire update is done on the main thread.

2) I was running in to these problems in the first place because of performance issues with the app. They seem to be coming from constant core data queries. I've set up an array to cache the last 10 objects my core data fetches has returned now which seems to have solved all my problems.
sneaky is offline   Reply With Quote
Reply

Bookmarks

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: 404
17 members and 387 guests
7twenty7, Alex-alex, Apptronics RBC, baja_yu, chiataytuday, dre, gwelmarten, ipodphone, jeroenkeij, jleannex55, matador1978, mbadegree, n00b, pbart, QuantumDoja, Retouchable, usernametaken
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,676
Threads: 94,125
Posts: 402,910
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jleannex55
Powered by vBadvanced CMPS v3.1.0

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