Function stored as variable can cause reference cycle? - ios

If I have a class, that stores an others class function as a variable, can that cause reference cycle?
For example
class ClassA {
var i = 0
func incrementI() {
i++
}
}
class ClassB {
private var function: () -> ()
init(function: () -> ()) {
self.function = function
}
func someFunc() {
function()
}
}
I cannot store in ClassB the variable function as weak or unowned, so can this cause reference cycle? Or this just reflects my poor understanding on reference cycles/function?

Reference cycles are exactly what they're name suggests. One object references another which references the original object. These can be made of two or more objects.
Why it's easy to make reference cycles using blocks or closures is because capturing self in a closure means the closure object has a reference to self. If self also has a reference to the closure than you have a reference cycle. I think your example is safe because you're passing the closure in ClassB's init which means that that closure shouldn't be able to have a reference to a non-existent object.
If your example took function as a method, then you'd have an issue as you could do this:
class ClassB {
...
func setSomeFunc(function : ()->()) {
self.function = function
}
func printSomething() {
print("Something")
}
}
...
func test() {
var x1 = {
print("Do Nothing")
}
var b : ClassB = ClassB(x1)
var x2 = {
b.printSomething()
}
b.setSomeFunc(x2)
}
In this example, we create x1 which has no external references.
[x1]
Then we create b with a reference to x1. This reference is added in ClassB's init.
[b]->[x1]
Then we create x2 with a reference to b. b is captured in the x2 closure which means that it will hold a strong reference to b.
[x2]->[b]->[x1]
We now assign a new function, x2, to b. This will break the reference from b to x1...
[x2]->[b]-x->[x1]
and replace it with a reference to x2.
[x2]->[b]-\ [x1]
/\ |
\-------/
As you can see, we now have a circular (or cyclical) reference. The only way to now break that reference is to set b's function member to reference something else, or to set x2's captured b value to something else.

Related

Unowned variables and async functions

I have a class that has an unowned variable. Like this:
class Student {
unowned var school: School
init(_ school: School) {
self.school = school
}
}
Now imagine I have an escaping async function in the class:
class Student {
unowned var school: School
init(_ school: School) {
self.school = school
}
// When this function is first called
// I can guarantee school has not been de-initialized
func reportAttendance(completionHandler: #escaping (() -> Void)) {
database.studentDidReportAttendance(student: self) {
// I cannot guarantee school has not been deinitialized
// when this callback function returns!
school.updateAttendance()
completionHandler()
}
}
}
My problem here is I can guarantee that when reportAttendance() it is called, that school has not been de-initalialized, but in the time it takes for the database to respond, I cannot guarantee that school won't be de-initialized. So if it is, then when the async block returns and tries to access school I get a run time error.
My question is how I can create a temporary strong reference to school when the function is first called, and then release it after I am able to safely run updateAttendance on school?
Thank you
You could create a local variable inside your function to keep a strong reference; see this test:
class School {
deinit {
print ("School.deinit")
}
}
class Student {
unowned var school:School
init(_ school: School) {
self.school = school
}
func printSchool() -> (() -> Void) {
let strongSchool = self.school
return { print ("I'm going to \(strongSchool)") }
}
}
if (1==1) {
var s:School? = School()
let student = Student(s!)
let p = student.printSchool()
s = nil
p() // Won't crash
}
Without strongSchool, the snippet crashes.
The thing is that we create a strong reference outside the closure - at this point in time you guarantee that it still exists - and then refer to this inside the closure. In this way, we
do not capture the student/self, but only the school
avoid a circular reference in case database is strongly reachable by the student and keeps itself the closure as a property (because self -> database -> closure -> self) and as long as school does not also reference database (well, it's more complicate to write than to think of)
But as #matt says, unowned is very dangerous and weak should be preferred, except for some uncommon cases where you have zillions of unowned objects which then would result in a large housekeeping overhead.
Seems like an x-y problem. If a Student's school can go out of existence while this Student still exists, that is an incorrect use of unowned. The precondition for saying unowned is that that must be absolutely impossible.

Weak Refrence in class return nil when created in first class's init

im trying to create weak reference class in another class, in first class's init i create instance of second class to use it in a function, but after init function is done , second class get destroyed and return nil,
here's a example code
//: Playground - noun: a place where people can play
import UIKit
class A {
weak var b : B?
init(){
NSLog("a Created")
self.b = B()
}
deinit{
NSLog("a Destroyed")
}
}
class B {
var arrayOfA : Array <A> = []
init(){
NSLog("b Created")
}
deinit{
NSLog("b Destroyed")
}
func printSomething(){
NSLog("print Something")
}
}
func test(){
let a : A = A()
a.b?.printSomething()
NSLog("still in test()")
}
test()
in console i see this
2016-04-04 00:34:50.516 MyPlayground[20009:921709] a Created
2016-04-04 00:34:50.516 MyPlayground[20009:921709] b Created
2016-04-04 00:34:50.516 MyPlayground[20009:921709] b Destroyed
2016-04-04 00:34:50.527 MyPlayground[20009:921709] still in test()
2016-04-04 00:34:50.527 MyPlayground[20009:921709] a Destroyed
and calling printSomething() will return nil
i dont want create B class outside of A class and also i want it weak for memory leak problems.
some how i want one to many relationship between two swift class , so i can load data from function
Since you declare b as weak, it gets deallocated as soon as it goes out of scope. In this case, as soon this code:
init(){
NSLog("a Created")
self.b = B()
}
finishes execution, self.b gets destroyed. This is the expected behavior. If you want b to hang around after the init then you should leave it as strong.
Alternatively you can do this:
func test(){
let b : B = B()
let a : A = A(b:b)
a.b?.printSomething()
NSLog("still in test()")
}
In A you can make a special init that takes in a B:
init(b: B){
NSLog("a Created")
self.b = b
}
With this code, A's reference to B is still weak, but since the B is still around in the test() method, it's also there when printSomething() is called.

Swift: Capture inout parameter in closures that escape the called function

I tried to write an "editor" class that could retain a reference to a property on a different object for later mutation. I first wrote the editor class to receive a closure for reading, and a closure for writing. This worked. I then tried to pass the parameter in question by (inout) reference, and then generate the getter / setter pair from that. This did not work. The Swift docs does say (paraphrasing) that Swift figures out when to copy, and when to not. I think I am up against unpredictability of that limitation, but thought I'd pose the question just the same.
Alternatively, is it possible to get a curried function for the individual getter and setter?
My code is:
class SomeModel : Printable {
var a:String
init(a:String) {
self.a = a
}
var description:String {
return "\(self.a)"
}
}
class Editor {
var getter:()-> String
var setter:(String)->()
init(getter:()-> String, setter:(String)->()) {
self.getter = getter
self.setter = setter
}
convenience init(inout bindTo:String) {
self.init(
getter:{ return bindTo },
setter: { v in bindTo = v })
}
func read() -> String {
return self.getter()
}
func write(value:String) {
self.setter(value)
}
}
func testBindTo() {
var readModel = SomeModel(a:"Did not capture by reference");
var bindForReading = Editor(bindTo: &readModel.a)
readModel.a = "captured by reference!"
println(bindForReading.read())
var writeModel = SomeModel(a:"Did not capture by reference");
var bindForWriting = Editor(bindTo: &writeModel.a)
bindForWriting.write("captured by reference")
println(writeModel)
}
testBindTo()
func testExplicitGetterSetter() {
var readModel = SomeModel(a:"Did not capture by reference");
var bindForReading = Editor(
getter: { readModel.a },
setter: { v in readModel.a = v })
readModel.a = "captured by reference!"
println(bindForReading.read())
var writeModel = SomeModel(a:"Did not capture by reference");
var bindForWriting = Editor(
getter: { writeModel.a },
setter: { v in writeModel.a = v })
bindForWriting.write("captured by reference")
println(writeModel)
}
testExplicitGetterSetter()
The results are:
Did not capture by reference
Did not capture by reference
captured by reference!
captured by reference
Thanks!
I don't think this is possible. And it shouldn't be possible, if you think about it, because it would be super unsafe.
Because closures can outlive the scope they were created in, captured variables must be stored with the block. But in order to be able to assign to the captured variable and share the state of that variable between the (one or more) block(s) that captured it and the original scope, the blocks cannot just capture the value of the variable (which would create independent copies of the variable), but capture a kind of "reference" to a shared copy. This means that assignable variables that are captured by blocks must be stored specially. In Objective-C, this is declared with __block. In Swift, this __block behavior is implicit.
However, in order for the block to modify an inout variable (potentially at a later time) as it is seen in the function caller's scope, that would mean that the passed variable in the caller's scope would also need to be stored in a way that can outlive the stack frame. But the caller function doesn't know this. All it knows from the type of the called function is that one of its parameters is inout; it doesn't know that the function plans to capture that inout variable in a block. So it doesn't know to prepare this __block storage for this passed variable.
It can be done as follows. )Notice that the closure and the inout param have the same lifespan.)
/// A class providing access to a resource with an inout parameter in an escaping closure.
class ProtectedResource<ValueType> {
private var protectedResourceArray = [ValueType]()
private var protectedResourceArrayLock = NSRecursiveLock()
private let opq = OperationQueue()
func performWithResource(block: #escaping (inout [ValueType]) -> ()) {
opq.addOperation { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.protectedResourceArrayLock.lock()
block(&strongSelf.protectedResourceArray)
strongSelf.protectedResourceArrayLock.unlock()
}
}
}
/// Some other class using that in out parameter.
func run() {
func updateArray(array: inout [String]) {
print("Performing on \(array)")
array.append("test")
}
protectedResource.performWithResource(block: updateArray)
protectedResource.performWithResource {
print("Performing on \($0)")
}
}

What is "self" used for in Swift?

I am new to Swift and I'm wondering what self is used for and why.
I have seen it in classes and structures but I really don't find them essential nor necessary to even mention them in my code. What are they used for and why? In what situations it's necessary to use it?
I have been reading lots of questions and answers for this question but none of them fully answers my questions and they always tend to compare it with this as in Java, with which I'm not familiar whatsoever.
Yes it is the same as this in Java and self in Objective-C, but with Swift, self is only required when you call a property or method from a closure or to differentiate property names inside your code, such as initializers. So you can use almost all of your class components safely without using self unless you are making the call from a closure.
“The self Property Every instance of a type has an implicit property
called self, which is exactly equivalent to the instance itself. You
use the self property to refer to the current instance within its
own instance methods.
The increment() method in the example above could have been written
like this:
func increment() {
self.count += 1
}
In practice, you don’t need to write self in your code very often.
If you don’t explicitly write self, Swift assumes that you are
referring to a property or method of the current instance whenever you
use a known property or method name within a method. This assumption
is demonstrated by the use of count (rather than self.count)
inside the three instance methods for Counter.
The main exception to this rule occurs when a parameter name for an
instance method has the same name as a property of that instance. In
this situation, the parameter name takes precedence, and it becomes
necessary to refer to the property in a more qualified way. You use
the self property to distinguish between the parameter name and the
property name.
Here, self disambiguates between a method parameter called x and
an instance property that is also called x:”
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2 Prerelease).”
This is how Ray Wenderlich recommends the use of self in Swift for their tutorials:
Use of Self
For conciseness, avoid using self since Swift does not require it to access an object's properties or invoke its methods.
Use self when required to differentiate between property names and arguments in initializers, and when referencing properties in closure expressions as required by the compiler:
class BoardLocation {
let row: Int, column: Int
init(row: Int, column: Int) {
self.row = row
self.column = column
let closure = {
println(self.row)
}
}
}
And this is GitHub's recommendations on self for their applications:
Only explicitly refer to self when required
When accessing properties or methods on self, leave the reference to self implicit by default:
private class History {
var events: [Event]
func rewrite() {
events = []
}
}
Only include the explicit keyword when required by the language — for example, in a closure, or when parameter names conflict:
extension History {
init(events: [Event]) {
self.events = events
}
var whenVictorious: () -> () {
return {
self.rewrite()
}
}
}
Rationale: This makes the capturing semantics of self stand out more in closures, and avoids verbosity elsewhere.
You will also use self a lot when creating your extensions, example:
extension Int {
func square() -> Int {
return self * self
}
// note: when adding mutating in front of it we don't need to specify the return type
// and instead of "return " whatever
// we have to use "self = " whatever
mutating func squareMe() {
self = self * self
}
}
let x = 3
let y = x.square()
println(x) // 3
printlx(y) // 9
now let's say you want to change the var result itself
you have to use the mutating func to make change itself
var z = 3
println(z) // 3
now let's mutate it
z.squareMe()
println(z) // 9
// now let's see another example using strings :
extension String {
func x(times:Int) -> String {
var result = ""
if times > 0 {
for index in 1...times{
result += self
}
return result
}
return ""
}
// note: when adding mutating in front of it we don't need to specify the return type
// and instead of "return " whatever
// we have to use "self = " whatever
mutating func replicateMe(times:Int){
if times > 1 {
let myString = self
for index in 1...times-1{
self = self + myString
}
} else {
if times != 1 {
self = ""
}
}
}
}
var myString1 = "Abc"
let myString2 = myString1.x(2)
println(myString1) // "Abc"
println(myString2) // "AbcAbc"
now let's change myString1
myString1.replicateMe(3)
println(myString1) // "AbcAbcAbc"
In what situations it's necessary to use it
It is necessary to use it only when the name of a local variable overshadows the name of a property.
However, as a matter of style (and readability), I always use it:
I use it with property names, because otherwise I am left wondering what this variable is (since it is neither locally declared nor an incoming parameter).
I use it as the receiver of function (method) calls, in order to differentiate such methods from top-level or local functions.
This is why we need self.
When we define a class, like:
class MyClass {
func myMethod()
}
We are creating a "Class Object". Yes, Class is an object too.
Then no matter how many instances are created using the class, all instances will have a reference pointer to its Class Object.
You can imagine that all instance methods defined by the Class are in the Class Object, and there will be only one copy of them.
That means all instances created using the Class are sharing the same method.
Now imagine you are the myMethod in the Class Object, and because you are shared for all instances, you must have a way to tell which instance you are working on.
When someone says instance1.myMethod(), it means "Hi! myMethod, please do your work and instance1 is the object you are working on".
To reference the object that the caller sent to you, use self.
“In practice, you don’t need to write self in your code very often. If
you don’t explicitly write self, Swift assumes that you are referring
to a property or method of the current instance whenever you use a
known property or method name within a method.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
https://itun.es/tw/jEUH0.l
The reserved word self in Swift is similar to this but it's not the same as in Java or JavaScript.
As #Dave Gomez correctly quoted:
Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself.
Here lies one of the main differences, because:
"Every instance" in Swift (at least for now) is almost every-thing.
In Java, for example, you can only use the word this inside an instance scope, in Swift you can use it almost every-where.
Here are a few examples:
//Example 1:
var x="foo"
x.self="bar".self//compiles and run
//Example 2:
print.self(x);//compiles and run
//Example 3:
func myOther(self otherSelf:Person){}
myOther(self: personObject);//compiles and run
//Example 4:
class Foo{
var bar=""
init(){
self.addSome()//this would be the same in Java
}
func addSome(){
//But definitely not this:
self.self.bar.self.self="some".self.self
}
}
//Guess what - also compiles and run...
let f=Foo()
print(f.bar)
See : Why 'self.self' compiles and run in swift for more information.
I arrived at this question while searching for self as a class function, which looks like this: Int.self, String.self, or YourClass.self
Previously, as near as I can tell, only Dmitri Pavlutin's answer touches on this, when he said:
When self is accessed in a type method (static func or class func), it refers to the actual type (rather than an instance).
When self is used this way, it actually returns what in Swift is called a Metatype. You can read the Swift documentation page on Types for more information.
There is also an article with more details about using and understanding metatypes called "What's .self, .Type and .Protocol? Understanding Swift Metatypes" on swiftrocks.com.
"How to use correctly 'self' keyword in Swift" explains self in detail.
self is a property on the instance that refers to itself. It's used to access class, structure and enumeration instance within methods.
When self is accessed in a type method like static func or class func, it refers to the actual type rather than an instance.
Swift allows omitting self when you want to access instances properties.
When a method parameter has the same name as an instance property, you have to explicitly use self.myVariable = myVariable to make a distinction.
Notice that method parameters have a priority over instance properties.
I'm a total noob at coding in general - and whilst these answers are great, from the perspective of a total noob who just wants it answered as practically as possible without all these difficult words and concepts, here's my Super Noob dumbed down version:
'self' is used because the coding application doesn't know which variable to use if you type the variable in the scope of your functions. It's all about the scope and making it clear which variable you're using if some other variable has the same name. Scope is the area inside the curly {} brackets. so for example:
{ scope1 {scope2} }
Here you don't need to use self:
class example {
private var exampleVar = “this is the class scope variable”
func x() {
//You don't have to use self here
print(exampleVar)
}
}
Here you do need to use self:
class example {
private var exampleVar = “this is the class scope variable”
func x(_ exampleVar: String) {
//It would be confusing which exampleVar is used here so you should use self
print(exampleVar)
print(self.exampleVar)
}
}
There's also this situation:
class example {
private var exampleVar = “this is the class scope variable”
func x() {
randomMethod { _ in
//This is not the class scope here, so we need to use self here.
//You will be flagged during build time of this if you don't use self.
print(self.exampleValue)
}
}
}
self is a property on the instance that refers to itself. It's used to access the class, structure and enumeration instance within methods.
When a method parameter has the same name as an instance property, you have to explicitly use self.myVariable = myVariable to make a distinction.
Notice that method parameters have a priority over instance properties.
struct Weather {
let windSpeed: Int
let chanceOfRain: Int
init(windSpeed: Int, chanceOfRain: Int) {
self.windSpeed = windSpeed
self.chanceOfRain = chanceOfRain
}
func isDayForWalk() -> Bool {
let comfortableWindSpeed = 5
let acceptableChanceOfRain = 30
return self.windSpeed <= comfortableWindSpeed
&& self.chanceOfRain <= acceptableChanceOfRain
}
}
// A nice day for a walk
let niceWeather = Weather(windSpeed: 4, chanceOfRain: 25)
print(niceWeather.isDayForWalk()) // => true
I have an elegant case for using self in Swift. I use it in blocks like this:
class MyBase {
private var baseValue: Int = 100
var block: ((Int)->())? = nil
func baseMethod(anotherValue: Int) {
guard let b = block else { return }
b(baseValue + anotherValue)
}
...
}
class MyClass {
init()
{
// Define base class block.
// This may hold self in block causing memory leaks
// if self is a strong reference
block = {
// indicate self is a weak reference
[weak self] (para) in
// guaranty self existence
guard let this = self else {return}
let value = this.value1 + para
// this call passes value to other obj's method
this.obj.method(value)
return
}
}
func callBaseBlock(otherValue: Int) {
baseMethod(otherValue)
}
private var value1: Int = 1 // ini value
private var obj: OtherClass // another class with method defined
...
...
}
This way, I guarantee that there will be no strong references to self in the block. The syntax is very clear. I use this way to prevent memory leaks.

Lazy/inline implement a protocol in Swift

I want to lazy/inline implement a protocol in Swift.
So in the point of the implementation I will have access to variables outside the protocol scope ,
Same as implementing a interface in Java without declaring a class:
class MyClass:UIView {
var someComponent:SomeInnerComponent = SomeInnerComponent();
var count:Int = 0;
var a = :SomeProtocol { //<----- IS THIS POSSIBLE, IF YES HOW ?
func a0() {MyClass.count--}
func a1() {MyClass.count++}
}
someComponenet.delegate = a;
}
protocol SomeProtocol {
func a0()
func a1()
}
editing----
thanks i look at this solution, and i didn't see how to access a variable of the parent class.
all the examples show an Anonymous class but no one of the examples is accessing the parent variables .
What you're looking for is an inner class (not necessarily an anonymous one), declared in a scope that lets it access the count variable of a MyClass instance, and that adopts a protocol defined at a different scope. Right now Swift has a few of those pieces, but it doesn't look like you can put them all together in any way that's as concise as what you might be looking for.
You might think about declaring an inner class:
class MyView: UIView {
let someComponent = SomeInnerComponent() // type SomeInnerComponent is inferred
var count = 0 // type Int is inferred
class Helper: SomeProtocol {
func a0() { count-- } // ERROR
// ...
}
init() {
someComponent.delegate = Helper()
}
}
But that won't work, because count is implicitly self.count, where self is a Helper instance, not the MyView instance that "owns" the Helper instance. And there isn't a way to reference that MyView instance (or its properties) from within a Helper's methods, because you could just as well construct a MyView.Helper() without having an existing MyView instance. Inner classes (or nested types in general) in Swift nest only in lexical scope, not in existential ownership. (Or to put it another way, since you referenced Java: all inner classes in Swift are like static inner classes in Java. There's no non-static inner class.) If that's a feature you'd like, though, it's probably worth telling Apple you want it.
You could also try declaring Helper inside MyView.init() -- in Swift you can nest type definitions anywhere, including inside functions or methods of other types. Defined there, it can refer to MyView's properties. However, now the type information for Helper is only visible inside of MyView.init(), so when you assign it to someComponent.delegate (whose type is just SomeProtocol), you can't make use of it... this crashes the compiler, even. (That's another bug to report, but it's hard to say whether the bug is really "compiler crashes on valid usage" or "code is bad, but compiler crashes instead of producing error".)
The closest solution I can come up with looks something like this:
class SomeInnerComponent {
var delegate: SomeProtocol?
}
protocol SomeProtocol {
func a0()
func a1()
}
class MyClass {
var someComponent = SomeInnerComponent()
var count = 0
struct Helper: SomeProtocol {
var dec: () -> ()
var inc: () -> ()
func a0() { dec() }
func a1() { inc() }
}
init() {
someComponent.delegate = Helper(
dec: { self.count -= 1 }, // see note below
inc: { self.count += 1 }
)
}
}
How it works:
Helper is an inner struct (could be a class, but a struct is simpler)
It implements the a0 and a1 methods, satisfying the requirements of SomeProtocol
The implementations of a0 and a1 call through to the closures dec and inc, which are stored properties (aka instance variables) of the Helper struct
You write (or otherwise specify) these closures when you construct a Helper instance (using the default member-wise initializer, Helper(dec: (Void -> Void), inc: (Void -> Void)))
Because you can write the closures when initializing a Helper, those closures can capture variables where you're calling the initializer, including the implicit self that refers to the MyClass instance creating the Helper.
You need both a0/a1 and dec/inc because you need closures (the latter), not methods, for capturing the enclosing state. And even though closures and funcs/methods are in many ways interchangeable, you can't create a method/func implementation by assigning a closure to a method/func name. (It'd be a different story if SomeProtocol required closure properties instead of methods, but I'm assuming SomeProtocol isn't something under your control.)
Anyway, this is kind of a lot of boilerplate and a layer of abstraction that you might not really need, so it's probably worth looking into other ways to architect your code.
Note: my example uses the closure { self.count -= 1 } where you might expect { self.count-- }. The latter doesn't work because that's an expression with a value, so Swift will interpret it as shorthand for the closure's return value. Then it'll complain that you assigned a () -> Int closure to a property that expects a () -> () (aka Void -> Void) closure. Using -= 1 instead works around this issue.
I would go for a different approach, I know this a pretty old topic but just in case someone else struggles with this issue:
class MyClass:UIView {
var someComponent:SomeInnerComponent = SomeInnerComponent();
var count:Int = 0;
init(){
// Assign the delegate or do it somewhere else to your preference:
someComponenet.delegate = ProtocolImplementation(myClass: self);
}
private class ProtocolImplementation: SomeProtocol {
let selfReference: MyClass
init(myClass: MyClass){
selfReference = myClass
}
public func a0(){
selfReference.count--
}
public func a1(){
selfReference.count++
}
}
}
protocol SomeProtocol {
func a0()
func a1()
}
By following this approach it's also possible to include the same protocol multiple times, lets say your Protocol supports a generic and you want to implement it twice. SomeProtocol< SomeObject > and SomeProtocol< OtherObject > could be both used this way if needed.
Kind regards

Resources