Revision [380]

This is an old revision of DummyProxy made by JohnMcIntosh on 2009-09-22 20:28:22.

 

One problem you face with the current dual thread architecture is the issue where you invoke message 'foo' on the main thread. This creates a NSInvocation instance to execute on the main thread. The main UI Thread receives notification that has to process your request as part of the UI RunLoop processing. However the timing is such that a touch event is pending and will be serviced first! This touch event triggers a call back to the SqueakProxy instance.

But now you have the Squeak VM waiting in the ObjectiveCBridge code for the main thread to complete, but you have the main thread waiting on the SqueakProxy instance lock to complete as it waits for VM which can't run to respond. A classic deadlock situation.

To avoid this here are some code samples which you setup in applicationDidLaunch: as proxy to either a UITextLabel or UISlider.
The thought is you can either set the text or value, and the proxy looks after sending the data to UITextLabel to UISlider if it exists.
Exists? Yes a problem is that when a memorywarning message is sent to a UIViewController it can dispose of all the UIViews. So
in viewDidLoad: you basically ask the proxy for the data to use for initializing your UITextLabel. Technically you would have to ask
the Squeak VM for the data, but having it shared in the proxy makes this task much easier. But you then must remember to only
get/put data via the proxy, versus tampering with the data in the actual UITextLabel.

//
//  DummyClassForUIView.h
//  WikiWikiServer
//
//  Created by John M McIntosh on 14/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface DummyClassForUIView : NSObject {
	NSObject	*cell;
}
- (void)setNeedsDisplay;
- (void) setNeedsDisplay: (BOOL) display;

@property (nonatomic,assign) NSObject *cell;

@end

//
//  DummyClassForUIView.m
//  WikiWikiServer
//
//  Created by John M McIntosh on 14/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import "DummyClassForUIView.h"


@implementation DummyClassForUIView
@synthesize cell;

- (void)setNeedsDisplay {
	[self setNeedsDisplay: YES];
}

- (void)setNeedsDisplay: (BOOL) display {
	if (!self.cell) return;
	if (!display) return;
	
	if ([NSThread  isMainThread]) 
		[(UIView *) self.cell setNeedsDisplay];
	else 
		[self.cell performSelectorOnMainThread:  @selector(setNeedsDisplay) withObject: nil waitUntilDone: NO];
}

@end

//
//  DummyClassForTextData.h
//  WikiWikiServer
//
//  Created by John M McIntosh on 10/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DummyClassForUIView.h"

@interface DummyClassForTextData : DummyClassForUIView {
	NSString	*text;
	NSString	*placeholder;
}
- (NSString *) getText;
- (void) setTextAndPassThru: (NSString *) aString setNeedsDisplay: (BOOL) display;
- (void) setPlaceHolderAndPassThru: (NSString *) aString setNeedsDisplay: (BOOL) display;

@property (nonatomic,retain) NSString *text;
@property (nonatomic,retain) NSString *placeholder;

@end

//
//  DummyClassForTextData.m
//  WikiWikiServer
//
//  Created by John M McIntosh on 10/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import "DummyClassForTextData.h"


@implementation DummyClassForTextData
@synthesize text,placeholder;

- (void) setPlaceHolderAndPassThru: (NSString *) aString  setNeedsDisplay: (BOOL) display {
	self.placeholder = aString;
	if (self.cell) {
		if ([NSThread isMainThread]) {
			((UITextField *)self.cell).placeholder = aString;
		} else {
			[self.cell performSelectorOnMainThread:  @selector(setPlaceholder:) withObject: aString waitUntilDone: NO];
		}
		[self setNeedsDisplay: display];
	}
}

- (void) setTextAndPassThru: (NSString *) aString  setNeedsDisplay: (BOOL) display {
	self.text = aString;
	if (self.cell) {
		if ([NSThread isMainThread]) {
			((UITextField *)self.cell).text = aString;
		} else {
			[self.cell performSelectorOnMainThread:  @selector(setText:) withObject: aString waitUntilDone: NO];
		}
		[self setNeedsDisplay: display];
	}
}

- (NSString *) getText {
	return self.text;
}


@end

//
//  DummyClassForUISlider.h
//  WikiWikiServer
//
//  Created by John M McIntosh on 10/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DummyClassForUIView.h"

@interface DummyClassForUISlider : DummyClassForUIView {
	float sliderValue;
}
- (void)setValue:(float)value animated:(BOOL)animated  setNeedsDisplay: (BOOL) display; 
@property (nonatomic,assign) float sliderValue;
@end

//
//  DummyClassForUISlider.m
//  WikiWikiServer
//
//  Created by John M McIntosh on 10/09/09.
//  Copyright 2009 Corporate Smalltalk Consulting Ltd. All rights reserved.
//

#import "DummyClassForUISlider.h"


@implementation DummyClassForUISlider
@synthesize sliderValue;

- init {
	[super init];
	sliderValue = 0.0;
	return self;
}

- (void)setValue:(float)value animated:(BOOL)animated  setNeedsDisplay: (BOOL) display {
	sliderValue = value;
	if (self.cell) {
		if ([NSThread isMainThread]) {
			[((UISlider *)self.cell) setValue: value animated: animated];
			[self setNeedsDisplay: display];
		} else {
			NSAutoreleasePool * pool = [NSAutoreleasePool new];
			NSMethodSignature* methodSignature = [((UISlider *)self.cell) methodSignatureForSelector:@selector(setValue:animated:)];
			NSInvocation *redrawInv = [NSInvocation invocationWithMethodSignature: methodSignature];
			[redrawInv setTarget: self.cell];
			[redrawInv setSelector:@selector(setValue:animated:)];
			[redrawInv setArgument: &value atIndex: 2];
			[redrawInv setArgument: &animated atIndex: 3];
			[redrawInv performSelectorOnMainThread: @selector(invoke) withObject: nil waitUntilDone: NO];				
			[pool drain];
		}
		}
}
@end


There are no comments on this page.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki