Will this object survive garbage collection in F#? - f#

I have a F# object like this:
type myObject() =
...
do
// calling a 3rd party lib that will do
// callbacks into this object's methods
and, in my main initialization, I do this:
let _ = myObject()
and go on with the rest of the code.
So, this object is setting up callbacks from a 3rd party library; the callbacks are going to land in this object but the object itself will not be referenced anywhere.
Question 1: will this object survive garbage collection
Question 2: if not, how to make it permanent

I think the question whether an object assigned to a placeholder _ will remain referenced from the location where it is declared is not the important question here. The important question is whether the external library will keep a reference to the object.
For most normal libraries that I can think of this would be the case. For example, consider something like this:
let register f =
let tmr = new System.Timers.Timer(1000.)
tmr.Elapsed.Add f
tmr.Start()
type MyObject() as this =
do register this.Foo
member x.Foo(_) = printfn "hi"
let _ = MyObject()
Here, the implementation of .NET timers will need to keep a reference to all the timers that you created (so that it can trigger them) and the timer we create keeps reference to the instance of MyObject. Regardless of whether _ creates a reference or not, the object will be referenced through the callback.
I can think of only a few ways in which you could register a callback without keeping a reference to the object - and those would most likely be by using native interop and unsafe code. If that's what you're doing, then it's better to create a global ResizeArray somewhere in a static field and keep a reference to your object there. In all other normal cases, you don't need to worry about this.

Related

Swift instance members & functions calls, could someone please clarify?

I'm practicing functions in an Xcode project (not playground, if that matters) and when I set the constant's function name to the above function's name, Xcode won't let me call it.
In other functions I've done the same thing I haven't had this error, I don't know why it's being triggered. I've tried putting the "let fun" constant into it's own struct but that just throws up a different error.
Your let fun = playstation(... is code. It is an executable command. Code consisting of an executable command cannot just live anywhere. It cannot exist just free-floating the way you have it. It must live in a method. For example you could put it inside your viewDidLoad method.
I am sure you know this, but I would like to say that learning the basics/fundamentals of the Swift language is really good if you use playgrounds for that or any other online IDEs which support Swift language.
Swift Playgrounds Experience is very, very different than what an iOS dev has to do later, i.e. when it actually comes to building an app.
Of course in app making, the Swift language is used, and one uses the knowledge he practiced using playgrounds. BUT!
When it comes to storyboards, ViewControllers, etc., one has to understand that this time, it is all about OOP (classes and structs).
It is about managing views, loading them, displaying UIView objects, implementing logic, saving/loading data...
So as people mentioned above, here you are creating an instance method and trying to use it as a regular function inside that Class.
To be able to use this function as you expect, you have to create an object/instance of this class, then you can call this function.
In this picture, you may see that using a static keyword also might be a solution. static func(){} means that this function belongs to the class itself. You access that func by using the full name of the type/class.
You cannot call an instance method to initialize this same exact instance property, so you will need to convert to a lazy var like so:
lazy var fun = playStation(game: "Monsters")
This way, the playStation(game: "Monsters") call will be triggered lazily, in the exact moment when the fun property will be called for the first time. This can be very useful, especially when performing more intensive tasks. The quirk with using lazy keyword is that it can only be used with var, which means the property can be mutated or set again - we lose immutability of let constants.
But maybe you do not want to store the fun value as an instance property and only want to get it once? You could then move it into the viewDidLoad implementation, so the fun is no longer an instance property but a local one, available only within the viewDidLoad method scope.
override func viewDidLoad() {
super.viewDidLoad()
let fun = playStation(game: "Monsters")
// do what you want with the `fun` value.
// maybe set it as text to some label?
myLabel.text = fun
}
You can read more about Lazy Initialization in this blogpost, also make sure to read the official documentation.

What should I do about frequently repeated constants?

This seems like a very simple question, but I can't find a clear answer. Also it's not specifically about swift or iOs, but I'm new to programming and swift is the only language I know anything about, so I don't know how to phrase it for a more general context.
I'm trying to write an iOs app and I found myself defining the same constants many times throughout my code.
I must have written this line about a hundred times, for instance:
let calendar = NSCalendar.currentCalendar()
Another example is getting my only User object from its persistent store:
let realm = try! Realm()
let user = realm.objects(User).first!
I define those calendar and user constants over and over throughout my whole code in classes and subclasses and extensions and computed properties.
That seems kind of stupid, though. I think I should be able to define calendar once and for all and just use it when I need it. So my first thought was to declare a global constant, but apparently everybody thinks anything with the word "global" in it should be avoided at all costs.
So what should I do? Is there another solution for this? Should I just keep writing the same stuff over and over again?
Thanks in advance,
Daniel
There are many different situations in which the best use of different approaches.
For example in your case:
let calendar = NSCalendar.currentCalendar()
currentCalendar is a static method that already returns a pointer to the object that you will use. And you don't need to set it to some constant for using with simple case:
print(NSCalendar.currentCalendar().calendarIdentifier)
Another thing that is most often better to use a shorter name for the object in your code when you need to refer to it often and this code looks much more readable:
print(calendar.calendarIdentifier)
If you have the functionality that you will often use in application from different places, you can just make it to the static method and does not create an object of this class every time you call it:
class NetworkConnection {
class func getDataFromServet(completion block: (data: SomeType) -> Void) {
...
}
}
And use it without object creation like:
NetworkConnection.getDataFromServer(completion: {(data: SomeType) -> Void in
...
})
If you need to use created object in many places, the best solution is not to make it global or singleton instance, but pass a pointer to it to the objects where you need to use it. This makes the code more readable, for example by looking at the input parameters of the init method, anyone can immediately understand which objects use this class for their work. And this class is easier to take from the project in a separate module and connect to another project. At that time, if you use the singleton instance, the class's interface is not clear what it can be used and this leads to code obfuscation. This applies and to the global objects.
If you're constantly changing it, why aren't you just using var instead of let?

Why can't I reassign an instance method in Swift?

So this question has an obvious answer: "because the compiler won't let you" but I'm hoping someone can explain to me why this part of Swift works the way it does.
I ran into this question because I was building a view controller that needed to satisfy a protocol (UIImagePickerControllerDelegate). The protocol requires a callback function to call after a user selected an image. I wanted to be able to change the callback behavior at runtime.
Coming from a Python background, I figured that should be easy: just define the callback method on my class to satisfy the protocol and then redefine it later by just reassigning to it. That works perfectly fine in Python:
class Foo(object):
def bar(self):
print "bar"
foo = Foo()
foo.bar() # output "bar"
def baz():
print "baz"
foo.bar = baz
foo.bar() # output "baz"
But it doesn't work in Swift (even though I can do very nearly the same thing by declaring a variable to hold a closure):
import UIKit
class Foo {
func bar() -> String {
return "bar"
}
var baz: ()-> String = {
return "baz"
}
}
let foo = Foo()
foo.bar() // output: bar
foo.baz() // output: baz
let gee = {
return "gee"
}
foo.baz = gee
foo.baz() // output: gee
foo.bar = gee // error: cannot assign to bar in foo
So the question...why does Swift work this way? It's clearly not because it's impossible to alter function routing at runtime (otherwise the closure assignment wouldn't work). My best guess is that it's analogous to the let/var distinction for variables and that using "func" is implicitly telling the compiler that a function should be immutable. And I grant that it may be better to make instance methods immutable by default. But it is annoying when we need to comply with rigid protocols from UIKit. At least it would be nice if I could use a variable to satisfy a function requirement in a protocol.
(For the curious: I worked around this issue by declaring an instance variable to hold a closure that can be reassigned. I then declared the required protocol function and made it do nothing but call the closure. Which might(?) cause a retain cycle, but works.)
The code the compiler is allowed to emit is fundamentally different.
Making a simple test, compiling with -Onone for readability, and disassembling with Hopper, you can see what's going on (comments added manually):
In the case of an "instance method"/function, they can be called after being looked up in the vtable — in this example, *(*rax + 0x48) and *(*rax + 0x70) are pointers to the functions, and they're passed rax (the object itself) as a parameter (this becomes self).
However in the case of a closure variable, *(*rax + 0x50) is a pointer to the getter for bar. The getter is called first, and returns the closure which is then called — (rax)(rdx).
So these are simply different things. If you have a modifiable property that stores a closure, then certainly you need to call the getter before you can call the closure (since the value could have changed by being set elsewhere). But simple function dispatch doesn't require the extra level of indirection.
Im not certain how functions and closures work behind the scenes in swift, but i would think a function in swift is basically like a function in c, its defined at runtime and thats it. its compiled and lives at a certain address in memory and anything referencing that function has to look at that memory address, and that cant change at runtime.
A closure i would see as like a function pointer + normal function combination in c. so its probably a limitation of the way they implemented the function in swift. in python maybe behind the scenes everything is implemented like a function pointer + normal function.
as to why swift didnt implement it like python, i think only someone who works at Apple could tell you that, but maybe there is some overhead with using everything like a closure instead of just plain functions, so they make you only use closures when needed and the rest should be functions.
also having functions immutable could be the reason why protocols work behind the scenes, maybe allowing you to change the function at run time would break the protocol system.
Im not sure if anyone here is really fit to answer this (besides an apple employee lurking here maybe), but this is my best guess

Where should I release static local and global variable with ARC?

I just created a new class in my project, subclass of UITableViewController and noticed that in the method tableView:cellForRowAtIndexPath: template, Apple still provide a static local NSString to use as a cell identifier.
I know that for static global/local variable we need to assign nil cause it's considered as strong.
So I asked myself the question : Where should I assign nil to static global variable ?
And static global variable ?
Thanks for the answers guys
A short answer to the "where should static global variables be released" is "nowhere".
Long answer goes like this: when you make a variable static or global, you want it to exist regardless of any instances of your classes coming into existence or being released. Simply speaking, you want your statics to always be there for you. Therefore, the only reason to release them would be if your program is about to exit. But if your program is exiting anyway, you might as well let the operating system handle the cleanup for you, and forget about releasing your global and static variables.
Note, however, that the use of static and global variables should be an exception, not a norm. You use them for a good reason, and exercise your best judgement to decide what should be static. Moreover, you should avoid referencing collections of non-static variables from static ones through a strong reference, because otherwise you may create hard-to-find memory leaks.
There is nothing wrong with a static local for the NSString used as your cell identifier: it takes very little memory, and it does not grow, so it's not a big deal that it is not released at the end of your program's run.
You don't need to do it, it will never be released and its ok since it is a global.
In ARC will be treated as strong for default and its lifetime it is equal to the application lifetime.
Static strings are a special case, and don't need to be released.
static variable, means it holds a strong reference to the object it points to.
static MyClass *var;
var = [MyClass instance];
Now var always holds strong reference to the above allocated object.so it will never be removed from memory.
But after some condition you no longer need that object,then simply
var =nil would work.
because now var points to nil and no longer points to created object.so that object will be deleted from memory.

Clarification on Apple's Block Docs?

I am working through some retain-cycle issues with blocks/ARC, and I am trying to get my head around the nuances. Any guidance is appreciated.
Apple's documentation on "Blocks and Variables" (http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html) says the following:
If you use a block within the implementation of a method, the rules
for memory management of object instance variables are more subtle:
If you access an instance variable by reference, self is retained; If
you access an instance variable by value, the variable is retained.
The following examples illustrate the two different situations:
dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});
I find this explanation confusing.
Is this appropriate use of the "by value" / "by reference" terminology? Assuming that these variables are of the same type (id), it seems like the distinguishing characteristic between them is their scope.
I do not see how self is being referenced in the "by reference" example? If an accessor method were being used, (e.g. - below), I could see self being retained.
doSomethingWithObject(self.instanceVariable);
Do you have any guidance on when one might want to do things one way or the other?
If conventional wisdom is to utilize the "by value" variables, it seems like this is going to result in a lot of additional code for additional variable declarations?
In a circumstance where nested blocks are coming into play, it seems like it may be more maintainable to avoid declaring the blocks inside of each other as one could ultimately end up with a potpourri of unintentionally retained objects?
Think of the case of using instanceVariable as an equivalent of writing self->instanceVariable. An instance variable is by definition "attached" to the self object and exists while the self object exists.
Using instanceVariable (or self->instanceVariable) means that you start from the address of self, and ask for an instance variable (that is offset of some bytes from the self object original address).
Using localVariable is a variable on its own, that does not rely on self and is not an address that is relative to another object.
As the blocks capture the variables when they are created, you typically prefer using instance variables when you mean "when the block is executed, I want to get the value of the instance variable at the time of the execution" as you will ask the self object for the value of the instance variable at that time (exactly the same way as you would call [self someIVarAccessorMethod]). But then be careful not to create some retain cycles.
On the other hand, if you use localVariable, the local variable (and not self) will be captured when the block is created, so even if the local variable changes after the block creation, the old value will be used inside the block.
// Imagine instanceVariable being an ivar of type NSString
// And property being a #property of type NSString too
instanceVariable = #"ivar-before";
self.property = #"prop-before";
NSString* localVariable = #"locvar-before";
// When creating the block, self will be retained both because the block uses instanceVariable and self.property
// And localVariable will be retained too as it is used directly
dispatch_block_t block = ^{
NSLog(#"instance variable = %#", instanceVariable);
NSLog(#"property = %#", self.property);
NSLog(#"local variable = %#", localVariable);
};
// Modify some values after the block creation but before execution
instanceVariable = #"ivar-after";
self.property = #"prop-after";
localVariable = #"locvar-after";
// Execute the block
block();
In that example the output will show that instanceVariable and self.property are accessed thru the self object, so self was retained but the value of instanceVariable and self.property are queried in the code of the block and they will return their value at the time of execution, respectively "ivar-after" and "prop-after". On the other hand, localVariable was retained at the time the block was created and its value was const-copied at that time, so the last NSLog will show "locvar-before".
self is retained when you use instance variables or properties or call methods on self itself in the code of the block. Local variables are retained when you use them directly in the code of the block.
Note: I suggest you watch the WWDC'11 and WWDC'12 videos that talks about the subject, they are really instructive.
Is this appropriate use of the "by value" / "by reference" terminology? It's at least analogous to the typical use. Copying a value to a local variable is like copying a value onto the stack; using an ivar is like passing a pointer to a value that's stored somewhere else.
I do not see how self is being referenced in the "by reference" example? When you use an instance variable inside a method, the reference to self is implied. Some people actually write self->foo instead of foo to access an ivar just to remind themselves that foo is an ivar. I don't recommend that, but the point is that foo and self->foo mean the same thing. If you access an ivar inside a block, self will be retained in order to ensure that the ivar is preserved for the duration of the block.
Do you have any guidance on when one might want to do things one way or the other? It's useful to think in terms of the pass by reference/pass by value distinction here. As AliSoftware explained local variables are preserved when the block is created, just as parameters passed by value are copied when a function is called. An ivar is accessed through self just as a parameter passed by reference is accessed through a pointer, so its value isn't determined until you actually use it.
it seems like this is going to result in a lot of additional code for additional variable declarations? Blocks have been a feature of the language for a while now, and I haven't noticed that this is a problem. More often, you want the opposite behavior: a variable declared locally that you can modify within a block (or several blocks). The __block storage type makes that possible.
it seems like it may be more maintainable to avoid declaring the blocks inside of each other as one could ultimately end up with a potpourri of unintentionally retained objects? There's nothing wrong with letting one or more blocks retain an object for as long as they need it -- the object will be released just as soon as the blocks that use it terminate. This fits perfectly with the usual Objective-c manual memory management philosophy, where every object worries only about balancing its own retains. A better reason to avoid several layers of nested blocks is that that sort of code may be more difficult to understand than it needs to be.

Resources