I run a very basic test application with tools and it finds a lot of memory leaks! Since I know that Apple guys perform memory leak checks when the application is sent to iTunes, I would like to investigate the problem.
My environment: MonoDevelop 2.4.2 with MonoTouch 3.2.4 on Mac OS X 10.6.6, oriented to iPad running iOS 4.2.1.
My test App simply shows a TableView populated with a list of 50 rows, grouping them by their starting letter.
Steps to reproduce the problem: create a new MonoDevelop-based iPad project, open the MainWindow.xib file with Interface Builder, put a new TableView in the window and create its output (named "tview") on the AppDelegate class. Then enter the following code in Main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace SimpleTable
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
public partial class AppDelegate : UIApplicationDelegate
{
private List<string> _names;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
_names = new List<string> { "Smith", "Jones", "Williams", "Brown", "Taylor",
"Davies", "Wilson", "Evans", "Thomas", "Johnson",
"Roberts", "Walker", "Wright", "Robinson", "Thompson",
"White", "Hughes", "Edwards", "Green", "Hall",
"Wood", "Harris", "Lewis", "Martin", "Jackson",
"Clarke", "Clark", "Turner", "Hill", "Scott",
"Cooper", "Morris", "Ward", "Moore", "King",
"Watson", "Baker", "Harrison", "Morgan", "Patel",
"Young", "Allen", "Mitchell", "James", "Anderson",
"Phillips", "Lee", "Bell", "Parker", "Davis" };
tview.Source = new MyTableViewSource(_names);
window.MakeKeyAndVisible ();
return true;
}
private class MyTableViewSource : UITableViewSource
{
private List<string> _sectionTitles;
private SortedDictionary<int, List<string>> _sectionElements = new SortedDictionary<int, List<string>>();
public MyTableViewSource(List<string> list)
{
_sectionTitles = (from c in list select c.Substring(0, 1)).Distinct().ToList();
_sectionTitles.Sort();
foreach (string element in list)
{
int sectionNum = _sectionTitles.IndexOf(element.Substring(0, 1));
if (_sectionElements.ContainsKey(sectionNum))
{
_sectionElements[sectionNum].Add(element);
}
else
{
_sectionElements.Add(sectionNum, new List<string> { element });
}
}
}
public override int NumberOfSections(UITableView tableView)
{
return _sectionTitles.Count;
}
public override string TitleForHeader(UITableView tableView, int section)
{
return _sectionTitles[section];
}
public override int RowsInSection(UITableView tableview, int section)
{
return _sectionElements[section].Count;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
string kCellIdentifier = "mycell";
UITableViewCell cell = tableView.DequeueReusableCell(kCellIdentifier);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, kCellIdentifier);
}
string display = _sectionElements[indexPath.Section][indexPath.Row];
cell.TextLabel.Text = display;
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
string display = _sectionElements[indexPath.Section][indexPath.Row];
showAlert("RowSelected", "You selected: \"" + display + "\"");
tableView.DeselectRow(indexPath, true);
}
private void showAlert(string title, string message)
{
using (var alert = new UIAlertView(title, message, null, "OK", null))
{
alert.Show();
}
}
}
}
}
I performed the following tests on the device:
commented
public override string TitleForHeader(UITableView tableView, int section)
procedure, launched application from tools: only leak detected; It seems that this leak is ALWAYS present, even when testing an empty application!
Test 1 Tools screenshot
uncommented
public override string TitleForHeader(UITableView tableView, int section)
procedure, the launched application from the tools: a lot of leaks were detected, and their number increases when the table scrolls up and down and / or any row is selected.
Test 2 Tools screenshot
replaced
return _sectionTitles[section];
at
public override string TitleForHeader(UITableView tableView, int section)
procedure with
return "Test Header…";
(thus using a constant string): same as in test n.2!
MonoTouch - ? , ( ) ?
, ... .