Какие правила управления памятью iPhone OS и практическое руководство Вы знаете?

Я изменил код, чтобы он был понятнее, интегрировав виджет (запись, кнопка), а затем добавил заданное значение «R Spark». В результате у меня был следующий код, который на данный момент работает. (Я скоро переделаю другие тесты), если есть какие-либо комментарии об этом новом, это будет приветствоваться.

Новый код:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

from tkinter import *
import time
import calendar
import sqlite3
import datetime

fen = Tk()
fen.title('ILS system ')
fen.resizable(0,0)
largeur=920
hauteur=660
fen.geometry('{}x{}+0+0'.format(largeur,hauteur))

#to calculate first and last day of the month:
now = datetime.datetime.now()
start_month = datetime.datetime(now.year, now.month, 1)
date_on_next_month = start_month + datetime.timedelta(35)
start_next_month = datetime.datetime(date_on_next_month.year, date_on_next_month.month, 1)
last_day_month = start_next_month - datetime.timedelta(1)
last_day=last_day_month.strftime('%Y-%m-%d')
first_day=start_month = datetime.datetime(now.year, now.month, 1).strftime('%Y-%m-%d')

def CreateTable_releves():

    conn1_releves = sqlite3.connect('bdd/test/test.db')
    curseur1_releves = conn1_releves.cursor()
    curseur1_releves.execute('''CREATE TABLE IF NOT EXISTS releves (id INTEGER PRIMARY KEY,time_releves TEXT NOT NULL, monitor1_releves TEXT NOT NULL,monitor2_releves TEXT NOT NULL)''')
    curseur1_releves.close()

def Add_To_Table_releves():

    time_releves_get = str(date_choisie.get())
    monitor1_releves_get = str(ent_mon1_mesure.get())
    monitor2_releves_get = str(ent_mon2_mesure.get())

    conn2_releves = sqlite3.connect('bdd/test/test.db')
    curseur2_releves = conn2_releves.cursor()
    curseur2_releves.execute('''INSERT INTO releves (time_releves,monitor1_releves,monitor2_releves) VALUES (?,?,?)''',(time_releves_get,monitor1_releves_get,monitor2_releves_get))
    conn2_releves.commit()
    curseur2_releves.close()

CreateTable_releves()

def monitoring () :

    fen_monitoring=Toplevel(fen)
    fen_monitoring.title('ddm axe')
    fen_monitoring.geometry('450x400+300+150')

    s= Scrollbar(fen_monitoring)
    T= Text(fen_monitoring,bg='powder blue',width=450,height=400)
    s.pack(side=RIGHT, fill=Y)
    T.pack(side=LEFT, fill=Y)
    s.config(command=T.yview)
    T.config(yscrollcommand=s.set)

    def update_releves():

        T.delete('1.0', END)
        T.update()

        conn = sqlite3.connect('bdd/test/test.db')
        curseur = conn.cursor()     
        for resultats in curseur.execute('SELECT * FROM releves where time_releves between ? AND ? ORDER BY time_releves DESC;', (first_day, last_day)):  

            contenu_table_releves= str(resultats[1])+"\t\t"+ str(resultats[2])+"\t\t"+ str(resultats[3])+"\n"

            T.insert(END,contenu_table_releves)  
        T.after(1000,update_releves)
        curseur.close()

    update_releves()

ent_mon1_mesure=StringVar()
ent_mon2_mesure=StringVar()
date_choisie=StringVar()

ent_mon1=Entry(fen,textvariable=ent_mon1_mesure)
ent_mon1.pack(side=LEFT,anchor=NW,padx=10,pady=10)

ent_mon2=Entry(fen,textvariable=ent_mon2_mesure)
ent_mon2.pack(side=LEFT,anchor=NW,padx=10,pady=10)

ent_time_releve=Entry(fen,textvariable=date_choisie)
ent_time_releve.pack(side=LEFT,anchor=NW,padx=10,pady=10)

bt_valider=Button(fen,text='valider', command=Add_To_Table_releves)
bt_valider.pack(side=LEFT,padx=10,pady=10)

bt_monitoring=Button(fen,text='afficher monitoring', command=monitoring)
bt_monitoring.pack(side=LEFT,padx=10,pady=10)

fen.mainloop()

Спасибо R Spark за помощь

5
задан Binarian 30 May 2014 в 17:54
поделиться

4 ответа

Фактически, каждый раз, когда вы инициализируете объект и имя метода включает в себя «init», вы отвечаете за его освобождение. Если вы создаете объект, используя метод Class, который не включает слово «init», то вы этого не сделаете.

Например:

  NSString *person = [NSString stringWithFormat:"My name is %@", name];

выпуск не требуется. Но:

  Person *person = [[Person alloc] init];

нужен релиз (как вы указали в своем вопросе). Аналогично:

  Person *person = [[Person alloc] initWithName:@"Matt"]];

также требуется релиз.

Это соглашение, а не правило языка, но вы обнаружите, что оно верно для всех API, поставляемых Apple.

4
ответ дан 13 December 2019 в 19:35
поделиться

Правила, которые я использую

  • Освободите все объекты, которые вы создаете, используя метод, имя которого начинается с «alloc» или «new» или содержит «copy».

  • Освободите все сохраненные вами объекты.

  • Не выпускайте объекты, созданные с помощью удобного конструктора + className. (Класс создает его и отвечает за его освобождение.)

  • Не выпускайте объекты, которые вы получаете другими способами, например mySprockets = [звездочки виджетов];

  • Если вы сохраняете полученный объект в переменной экземпляра, сохраните его или скопируйте. (Если это не слабая ссылка - просто указатель на другой объект, обычно для того, чтобы избежать циклических ссылок.)

  • Полученные объекты действительны в рамках метода, в котором они получены (обычно), и также действительны, если переданы обратно вызывающему.

Несколько хороших ссылок:

  1. http://www.gehacktes.net/2009/02/iphone-programming-part-2-objective-c-memory-management/
  2. http://mauvilasoftware.com/ iphone_software_development / 2008/01 / iphone-memory-management-a-bri.html
4
ответ дан 13 December 2019 в 19:35
поделиться

Управление памятью может показаться утомительным, когда вы видите, что segfaults проистекают из каждой кажущейся невинной строки кода, но на самом деле это довольно легко, когда вы освоите его. Потратьте немного времени на чтение этой страницы , а затем документации Apple , и вы должны без проблем писать код без ошибок.

2
ответ дан 13 December 2019 в 19:35
поделиться

Я склонен создавать только автоматически выпущенные объекты, используя метод класса или автоматически выпуская его сразу после создания, если только я не могу указать причину этого. Например:

  • Я присваиваю его переменной-члену, потому что намерен удерживать его некоторое время.
  • Я только создаю его, чтобы немедленно передать его другому методу, и отправляю ему сообщение об освобождении прямо после вызова этого метода.
  • По соображениям производительности мне нужно освободить эту память до того, как будет выпущен ближайший NSAutoreleasePool, например, при создании большого числа объектов внутри цикла или при хранении большого количества данных (например, , images).

Таким образом, у меня меньше шансов протечь объекты. По умолчанию я создаю их с автоматическим выпуском, и когда я принимаю осознанное решение не делать это автоматически, Я сразу же столкнулся с вопросом о том, где они будут освобождены.

Для свойств объекта вместо того, чтобы освобождать их в моем методе dealloc, я хотел бы присвоить им nil. Таким образом, сохраненные или скопированные свойства отправляются в релиз, а назначенные свойства просто перезаписываются, и мне не нужно обновлять свой метод dealloc, если я изменяю свойство на / из сохраненного.

1
ответ дан 13 December 2019 в 19:35
поделиться