Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-9492] iOS: loss of reference to functions using event handlers

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2013-07-16T09:39:27.000+0000
Affected Version/sRelease 2.1.0, Release 2.0.1
Fix Version/sRelease 3.0.0, Sprint 2012-19 Core, 2012 Sprint 19
ComponentsiOS
Labelscore, module_media, qe-testadded
ReporterFederico Casali
AssigneeMax Stepanov
Created2012-06-11T17:44:43.000+0000
Updated2013-07-16T09:39:27.000+0000

Description

Problem description

A function defined inside an event listener, without an external reference, fails to be invoked after a few calls.

Steps to reproduce and sample code:

1. Run the sample code below. 2. Launch app, tap "Open Camera" button. 3. Tap "Take Photo" button, alert displays for success callback it's correctly triggered. 4. Tap "Take Photo" button again and repeat multiple times to simulate taking photo photos in succession. Success callback does not fire. 5. Tap "Close Camera" button, camera does not close.
var win = Ti.UI.createWindow({
	backgroundColor: '#efefef',
	title: 'Test'
});

openCameraButton = Ti.UI.createButton({
	style: Ti.UI.iPhone.SystemButtonStyle.BORDERED,
	title: 'Open Camera'
});

openCameraButton.addEventListener('click', function(e) {
	var cameraOverlay = Ti.UI.createView();
	
	var takePhotoButton = Ti.UI.createButton({
		backgroundColor: '#fff',
		backgroundSelectedColor: '#efefef',
		borderColor: '#000',
		borderRadius: 17,
		borderWidth: 1,
		bottom: 65,
		color: '#000',
		height: 34,
		opacity: 0.4,
		title: 'Take Photo',
		width: 100
	});
	
	var closeCameraButton = Ti.UI.createButton({
		backgroundColor: '#fff',
		backgroundSelectedColor: '#efefef',
		borderColor: '#000',
		borderRadius: 17,
		borderWidth: 1,
		bottom: 65,
		color: '#000',
		height: 34,
		opacity: 0.4,
		right: 10,
		title: 'Close Camera',
		top: 10,
		width: 150
	});
	
	takePhotoButton.addEventListener('click', function(e) {
		Ti.Media.takePicture();
	});
	
	closeCameraButton.addEventListener('click', function(e) {
		alert('closing camera');
		Ti.Media.hideCamera();
	});
	
	cameraOverlay.add(takePhotoButton);
	cameraOverlay.add(closeCameraButton);
	
	Ti.Media.showCamera({
		success: function(e) {
			alert('success callback');
		},
		cancel: function() {
			Ti.API.info('cancel callback');
		},
		error: function(e) {
			Ti.API.info('error callback');
		},
		allowEditing: false,
		animated: false,
		autohide: false,
		mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO],
		overlay: cameraOverlay,
		saveToPhotoGallery: false,
		showControls: false
	});
});

win.add(openCameraButton);
win.open();

Additional notes

In the sample code above, objects are defined inside 'openCameraButton.addEventListener' function. Moving them outside of the function will solve the problem for this particular case. Looks like to the references to the objects in the function are lost (maybe after items have been garbage collected). Tickets references: http://support.appcelerator.com/tickets/APP-397683 and http://support.appcelerator.com/tickets/APP-499212

Comments

  1. Max Stepanov 2012-09-13

    PR pending https://github.com/appcelerator/titanium_mobile/pull/2942
  2. Natalie Huynh 2012-12-04

    Tested with 3.0.0.v20121130200208 on iPhone 4 5.1.1
  3. Priya Agarwal 2013-07-16

    Reopening just to updated label.
  4. Priya Agarwal 2013-07-16

    Updated label. Verified with: Titanium Studio:3.1.2.201307091843 Titanium SDK: 3.1.2.v20130710144553 acs:1.0.3 alloy:1.1.3 npm:1.2.14 titanium:3.1.1 titanium-code-processor:1.0.1 OS: OSX 10.8 Device:iphone4(v5.1) Xcode: 4.5.1

JSON Source