2013-10-12 3 views
1

Должен ли я в Titanium Mobile закрыть результаты, заданные перед созданием нового, или он автоматически «закрывается» после того, как нет ссылки на него?Должен ли я закрыть Result Set перед созданием нового?

Например, что-то вроде этой безопасности и утечки памяти?

var db = db.open("db_name"); 
var rs = db.execute("SELECT * FROM table"); 

while(rs.isValidRow()){ /* working with the resuls... */ } 

// I make another select before closing the previous (current) results set 
rs = db.execute("SELECT * FROM another_table"); 

while(rs.isValidRow()){ /* working with the results... */ } 

// Once I am completely done I close the RS and DB 
rs.close(); 
db.close(); 

Или мне нужно закрыть набор результатов каждый раз, когда требуется новый выбор.

var db = db.open("db_name"); 
var rs = db.execute("SELECT * FROM table"); 

while(rs.isValidRow()){ /* working with the resuls... */ } 

// Close RS and then initialize a new one 
rs.close(); 
rs = db.execute("SELECT * FROM another_table"); 

while(rs.isValidRow()){ /* working with the resuls... */ } 

rs.close(); 
db.close(); 

ответ

0

Согласно документации http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Database.ResultSet

На платформе IOS, закрытие базы данных также закрывает набор результатов, то есть, вы только можете получить доступ к набору результатов, если база данных в настоящее время открыт

Это также можно найти в исходном коде Titanium Mobile (IOS) в iphone/Classes/TiDatabaseProxy.m (see on Github)

глядя на исходный код (один и тот же файл) мы Ĉ a см., что TiDatabaseProxy создает массив, который используется для хранения набора результатов, а затем используется для закрытия всех из них. (see on Github) Android выглядит, однако, по-разному, и по этой причине существует несколько платформ (а также для «самого чистого» кода), лучше всего закрыть результаты, прежде чем инициализировать новую в другом (на другой платформе) не могут быть освобождены, что создаст утечку памяти.

1

Вы должны закрыть ResultSet, как только сможете получить все необходимые данные все время. Переписывающая переменная, которая указывает на ResultSet, не закрывает ее, поэтому ваш второй пример более подходит.

КПП. Вы объявляете RS дважды, поэтому она должна быть:

var db = db.open("..."); 
var rs = db.execute("SELECT * FROM table"); 

// while(rs.isValidRow()){ ... } 

rs.close(); 

rs = db.execute("SELECT * FROM another_table"); // Another select 

// while(rs.isValidRow()){ ... } 


rs.close(); 
db.close(); 

или даже лучше, чтобы избежать путаницы, что происходит в вашем коде:

var db = db.open("..."); 
var rs1 = db.execute("SELECT * FROM table"); 
var rs2 = db.execute("SELECT * FROM another_table"); 

// while(rs1.isValidRow()){ ... } 

rs1.close(); 

// while(rs2.isValidRow()){ ... } 

rs2.close(); 

db.close(); 

Edit: Read Best practises for SQLite, чтобы увидеть более подробную информацию, как вам должен создавать, выполнять и закрывать операции с базой данных.

+0

Спасибо, и что с этим, все в порядке? 'var db = db.open (" ... "), \t someName = db.execute (" SELECT column FROM table WHERE id = 1 "). field (0); // Выбираем только один элемент db.close(); ' – 0101

+0

Вызывая' db.execute() ', вы все равно создаете ресурс, который занимает пространство внутри памяти до тех пор, пока не вызывается' .close() '. Не назначать ресурс переменной не поможет. Также я не понимаю, чего вы пытаетесь достичь. Если вы будете писать open() и close() после каждого запроса, вы создадите какую-нибудь приятную функцию, которая принимает запрос как параметр. – daniula

Смежные вопросы