Is the following true:
weak = unsafe_unretain = assign
strong = retain
If it is why they are duplicated ? Which one should we choose?
No, it's not true. weak means that the object is not retained, and additionally, the variable/property will automatically be set to nil when the object is deallocated. unsafe_unretained means the object is not retained, but there is no automatic zeroing. strong and retain are equivalent.
assign is typically used for primitives, like int or double, since you're just assigning. unsafe_unretained is used for Objective-C objects that you know are not being retained, and understand why that's unsafe. weak is a new feature introduced in iOS 5 that is like unsafe_unretained, but has different semantics with ARC. Check out Apple's Advanced Memory Management guide for more info.
In practice, you'll almost never use unsafe_unretained if you're targeting iOS 5 or higher.
strong: variable is retained during its scope. retain also works as a synonym for strong.
copy: creates and retains a copy.
weak: use it to point to an object without claiming ownership. Once the object is released, the pointer will be nil'ed.
unsafe_unretained: same as weak but doesn't nil the pointer after release.
assign: primitive values.
If you're targeting iOS 4, you cannot use weak. Use unsafe_unretained instead.
Before ARC, the default on properties was assign, now the default is strong.
weak != unsafe_unretain
weak will automatically convert its pointer to a nil if the object it is pointing to is deallocated.
Going forward you should use strong & weak for objects and assign for primitive types
Related
This is allowed in Swift 5.0:
class Person {
unowned var child: Person?
}
This is supported by this release notes:
unowned and unowned(unsafe) variables now support Optional types.
(47326769)
I understood exactly the difference between weak and unowned in Swift 4.2 and before. However, I am not sure why Apple decided to make the unowned an optional type. Even in the docs (which are docs for Swift 5.0) this implemented 'proposal' (where can I even find that proposal with the motivation to add optional unowned references?) isn't updated, because it says:
An unowned reference is expected to always have a value. As a result,
ARC never sets an unowned reference’s value to nil, which means that
unowned references are defined using non-optional types.
Above isn't true anymore. The only functional difference that Apple states is that an unowned reference is expected to have an equal or longer lifetime than the object holding that reference. Well, I am curious about the technical use of this.
What difference does it make when I use a weak reference vs an optional unowned reference? Or is the only difference that optional unowned should be used when the referencing object has a longer lifetime? I would expect there must be more...
You've misunderstood the release note and the meaning of the change in the language.
why Apple decided to make the unowned an optional type
They didn't. You can, and usually will, still say
unowned let owner : MyViewController
The only change here is that the unowned variable can be an Optional, which was illegal previously. This change takes care of an annoying edge case, that's all.
Above isn't true anymore
Yes, it is. Things are completely unchanged from before:
Weak references must be typed as Optional; they do not retain the object referred to, but they track the object referred to, and revert to nil if that object goes out of existence.
Unowned references do not retain the object referred to and do not track the object referred to, so it's up to you to prevent that object from going out of existence or you may end up with a dangling pointer and a crash.
The only thing that's changed is that there used to be an additional rule that an unowned reference type could not be an Optional. That rule is now gone.
As you rightly point out, if the unowned reference type is an Optional, this must be a var reference, not a let reference (because having this be an Optional would make no sense if you didn't have the power to change it from nil to an actual value and vice versa).
A typical use case is very much like what you yourself provided:
class Node {
unowned var parent: Node?
}
It seems reasonable to say that this Node may or may not have a parent (because it might be at the top of the graph), but that if it does have a parent, that parent should be unowned (a parent should retain its child, but a child should not retain its parent). Previously, the only way to say that was to make this a weak reference, which entails some unnecessary overhead, and is otiose, because we can absolutely guarantee that if a node has a parent, the parent will outlive the child. Now, you can say what you mean, which is generally a good thing.
I'm confused about the type requirements and declaration restrictions for Swift capture specifiers. The documentation says that weak references must be var and "of optional type", and that unowned references must be of non-optional type. But Apple's own API reference has examples of unowned(unsafe) references declared as optionals, while the Xcode interface builder creates weak outlets and actions that are implicitly unwrapped (which is not always clearly "of optional type" in the language reference).
What types are required for each of the Swift capture specifiers? Which must be var and which can be let?
FWIW, I think its
weak can be Type? or Type!, but not Type; and must be var
unowned(safe) (same as unowned) must be Type; and may be let
unowned(unsafe) can be Type? or Type!; and may be let
but I'm far from sure.
First the Cocoaor Cocoa touch APIs are imported in swift fromobjective-c`. They are mapped in swift with best possible ways.So that both can interoperable.
Those unowned(unsafe) properties are marked as assign in ObjC. These are unsafe and ARC doesn't retain the object, and it doesn't make sure the reference gets reset to nil if the object is deallocated. These are old apple API and not changed with ARC and remain asassignbut you should makedelegateweak`
Do not look for headers for best practices in swift they have made many tricks to make swift and objective-c interoperable and if you do what headers do than you loose all safety swift proveide.
You are right
weak should be optional as contain nil automatically if objects get deallocate and no other pointer retain it
unowned(safe) should not be optional and will not reset to nilif objects deal-located
unowned(unsafe) can or can not be optional as it not provide any safety by ARC for object deal-location and do not reset to nil.You should not use this in swift program.Use unowned if needed.It is just for interoperability.
weak is always var because it can be changed when objects deallocate and set to nil.
unowned(safe) and unowned(unsafe) can be both var or let as they are dependent on you and run-time will not change these variables.
Note:You can not declare a unowned(unsafe) as optional in swift program.Its for just interoperability and should not be used in swift.They have made this because of assign or unretain properties can be nil
I find the following code in UITableView class,
unowned(unsafe) var delegate: UITableViewDelegate?
so I wander how to define a unowned(unsafe) reference delegate for UIView, then I encounter the following error when I write the unowned(unsafe) keyword in my class,
/Users/larryhou/Documents/Xcode/AtomicElements/AtomicElements/AtomicElementView.swift:32:25: 'unowned' cannot be applied to non-class type 'AtomicElementViewDelegate?'
protocol AtomicElementViewDelegate:NSObjectProtocol
{
func didTap(target:AtomicElementView, sender:UITapGestureRecognizer)
}
I can only use weak keyword, but I want keep the reference until UIView is deallocated.
Those two designations - unowned and weak - are equivalent from the perspective of references. Where they differ is the presumption of existence - in Swift, unowned instances are presumed to always exist as long as reference to them does, whereas weak instances are optionals - they may exist, or they may not, so you need to use optional chaining or some other means of working with them.
In UIKit, the delegate pattern with UIView subclasses is to declare them as weak because the delegate is nearly always the view controller that owns the view that the subclass is a subview of. Declaring a delegate as strongly referenced in that situation would set up a reference cycle, hence delegates are typically declared with the weak keyword. If you have a different situation, you can allow your delegate to be strongly referenced by simply leaving out the weak keyword.
In this particular case, unowned (unsafe) is an artifact of being bridged from ObjC.
how to define a unowned(unsafe) reference delegate for UIView
You can't. And you shouldn't want to. unowned(unsafe) is a way of expressing the Objective-C non-ARC assign policy, i.e. no memory management. It is horrible and dangerous (and can cause crashes). The name tells you what the problem is. It is unsafe!!! There is no Swift equivalent because Swift has built-in memory management. This is one of the reasons why Swift is good. Don't worry be happy.
But do be careful, because this designation is warning you that if the delegate goes out of existence while the UITableView still exists, you will crash because the table view will not know this and may try to send a message to the non-existent delegate.
I have few questions.
1)where assign property will take memory as we dont need to release for reducing reference count?
2)what is the difference between auto zero reference and non-auto zero reference?how does it work? how will take memory?
weak applies to objects (they have reference counts and all the stuff), but weak references don't increase refcount. But once the object is deallocated (from anywhere in the code), any weak reference to that object is set to nil. This is extremely useful, because if you use only strong and weak references, you can't end up with an invalid pointer (pointer to an already deallocated object).
assign does absolutely nothing with the reference, it is usually used for ints, floats and other non-object types. You can of course assign an object reference to such a variable, but if the object is deallocated, you will still have a pointer to it's memory (which is garbage now, and will hurt you when you use it).
Your concerns about "memory use" are weird - references don't take memory, object do. But you can't deallocate an object if you are going to use it. The simple rule for beginners is: for objects, use strong references whenever you can. When you have a reason not to use strong reference, use weak (usually for delegates and datasources). For primitive types (int, float, CGRect, ...) use assign, because they are not objects.
assign is like weak but there's no zeroing of the pointer when it leaves the heap. So, it's not as safe as weak.
As strong and weak properties are new in iOS 5.
If any one tell me which property is used when.
When we should use strong or when we should use weak?
#property(nonatomic,strong)
#property(nonatomic,weak)
Review Apple documentation for the Automatic Reference Counting (ARC)
If you don't have time for reading it:
ARC introduces several new lifetime qualifiers for objects, and weak references. A weak reference does not extend the lifetime of the object it points to, and automatically becomes nil when there are no strong references to the object.
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong
references to the object.
As iOS 5 ARC automatically nullifies weak links, when an object is unloaded its object hierarchy is automatically set to nil. Because this reason, Weak is the recommended relationship for all outlet properties. These view objects are already part of the view controller’s view hierarchy and don’t need to be retained elsewhere. The big advantage of declaring your outlets weak is that it saves you time writing the viewDidUnload method.
Check a very detailed document refering memory management. It is previous to ARC, but it will help you to understand the memory management. The retain keyword for properties still works with ARC and is simply a synonym for strong. Or another specific ARC tutorial.
Strong means that as long as this property points to an object, that object will not be automatically released. In non-ARC it's a synonym for retain.
Weak instead, means that the object the property points to, is free to release but only if it sets the property to nil. In ARC you use weak to ensure you do not own the object it points to.
strong is like retain, weak is like assign. The main difference is that weak properties turn to nil when the object that is assigned to them gets released.
eg:
#property (nonatomic, weak) id test;
...
- (void)example
{
id foo = [[NSObject alloc] init];
self.test = foo;
foo = [[NSObject alloc] init];
assert(self.test == nil);
}
There are following difference between strong and weak.
1.If we declare variable strong then it is not deallocated by compiler till the Application instance in memory.When we set nil value to that reference then it deallocates by compiler, by default any local variable as strong variable.
For instance:-
var str = "hello world"
if we set str = nil then it is deallocated.
2.If we declare variable as strong then it is retain by other instance(Class) and it's retain count increment by 1.
Weak property.
1.When we declare weak property then it only contains data/instance address till strong reference is in memory if strong variable reference deallocated it is automatically set to nil.
For ex:-
var str = "hello world"
weak var stringVar = str
suppose str contain 200 heap address and we set str = nil, then automatically weak property reference set to nil by the compiler.
So that's the reason in stoary board ref controller, Main view only set to strong and other are weak for ex- we can see UIButton,UILabel out let e.t.c.