2016-12-02 2 views
1

Чтение my own answer. Я полностью понимаю, почему нам нужен слабый сам для членов/свойств. Они могут создавать циклы памяти. Но свойства имеют место памяти. У функций также есть ячейки памяти ?! Я имею в виду, что это не функция, которая просто происходит на ходу? Если это так, то тип ячейки памяти отличается от местоположения свойства?Зачем нам нужен слабый Self для функций/методов в пределах замыканий?

Если я не использую self, я получаю эту ошибку.

Звонок в метод 'alertFunc' в закрытии требует явного «я». для замыкающих захвата семантики явных

, который немного отличается от:

Ссылки собственности «окна» в закрытии требует явного «я». для замыкающих захвата семантики явного

Моего код выглядит следующим образом:

let another = UIAlertAction(title: "Log", style:UIAlertActionStyle.Default){action in 
logAction() 

} 

private func logAction() { 

print("health") 

} 
+1

Функции являются первоклассными типами в Swift. Очевидно, что они семантически разные, но практически говорящие функции могут быть, хотя и просто различной переменной. – PeejWeej

ответ

1

кредит IOS ботаников я знаю из Meetup

Т.Л., др вам нужно использовать себя для пример методов, но не нужен для класс методов. Класс может иметь много экземпляров, но он может иметь только одно объявление о себе (который также содержит его тип/класс/статические функции)

Почему возникает ошибка 1: Голые в виду alertFunc мог иметь ссылку свойство

это могло быть:

private func logAction() { 

print("someProperty = \(self.someProperty") 

} 

Так что в данном случае это явно видно, что вы в конечном счете, ссылки на свойство


Почему возникает ошибка 2: Если у вас нет ссылки на self внутри вашей функции, еще потому, что вы написали это как метод экземпляра, самость неявно передается, но мы не видим!

Метод экземпляра действительно просто синтаксический сахар для функции, которая принимает экземпляр для первого параметра, который сам передаются автоматически

под капюшонами он может что-то выглядеть следующим образом

private func alertFunc (_ instance: MyType) { 

print("someProperty = \(instance.someProperty") 

} 

// and actually the call to it *may* look something like this: 

MyType.someFunc(self) 

Мы никогда не увидим, что меня пропустили ... Это синтаксический сахар, который нас обманывает.

Итак, если ваш метод не использует внутреннюю часть (т.не зависит от состояния, например, в любом случае), то на самом деле это, вероятно, лучше, чтобы сделать его static/type/class method или свободная функция


Alternative1: использовать бесплатную функцию.

class someClass { 

... 

} 
func freeFunc { 
print("Hi this is a free function, written outside the scope of any class...") 
} 

И тогда в вашем закрытии вы называете его помощью freeFunc()

Alternative2: Используйте функцию класса.

class someClass { 
// some other code 

     class private func alertFunc() { 
     print("Hi this was a class function, see the class at the beginning of the func definition") 
} 
} 

И тогда в вашем закрытии вы называете его помощью yourClassName.alertFunc()


Но почему это то, что классовые функции не создают циклы памяти, а функции экземпляра делать? Я рад, что вы спросили:

Например mehtods, для каждого экземпляра, который вы протянуть руку, есть место в памяти нового и генерировать новый цикл памяти, которая будет сохраняться deallocations.

Для методов класса, каждый раз, когда вы обращаетесь к методам класса/типа, вы обращаетесь к методу класса/типа , и, сохраняя этот метод класса, вы не будете его создавать и он создан только один раз!

В Objective-C (и C++) Тип метода:

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

+0

Итак, из этого. Лучше использовать функции static/class, а не обычные функции? (Распределение памяти мудрый) –

+0

Итак, если я вызываю функцию внутри класса снова и снова, он просто делает все больше и больше экземпляров самого себя? Но что, если это просто изменение значения s внутри класса? (Извините, я новичок в теме выделения памяти) –

+0

@ZonilyJame * Итак, из этого. Лучше использовать функции static/class, а не обычные функции, тогда * <- на мгновение забыть проблему распределения памяти. И только подумайте о * цели * функции. Вы полностью понимаете, почему у нас есть метод типа/класса vs instance? – Honey

2

Когда вы пишете logAction(), это косвенно означает self.logAction(). (Методы вызываются в каком-то экземпляре, когда вы не укажете, по умолчанию он равен self.) Таким образом, вы используете self внутри крышки, что означает, что закрытие захватывает self, и имеет ли он фиксированную сильную или слабую ссылку последствия для управления памятью ,