Why cannot NSTextView for a weak reference? - objective-c

I noticed than in OSX, the NSTextView cannot for a weak refference (if you try to link it weak, you will get)
Cannot form weak reference to instance (0x600000122da0) of class NSTextView. It is possible that this object was over-released, or is in the process of deallocation.
also the outlet from XCode is created as assign by default
Why there cannot be a weak reference? What can be the reason?

Check FAQ here Transitioning to ARC Release Notes:
Q:Which classes don’t support weak references?
A:You cannot currently create weak references to instances of the
following classes: NSATSTypesetter, NSColorSpace, NSFont, NSMenuView,
NSParagraphStyle, NSSimpleHorizontalTypesetter, and NSTextView.
etc.

Read the message carefully. Read past the word NSTextView. It tells you exactly why at this moment you cannot create a weak reference to the NSTextView. You just have to read it.
For example, while dealloc is running, you cannot create new weak references anymore because the object will be going away and all weak references will be set to nil. Trying to assign the object to a weak variable will keep that variable nil, even though the object is not nil (yet).
And this has nothing to do with NSTextView.

Related

How does UIView prevent retain cycle?

Subview has a reference to superview, while superview also has reference (subviews) to subview.
I'm wondering why this doesn't cause retain cycle?
UIView's superview property is declared as
#property(nonatomic, readonly) UIView *superview;
In Objective-C, properties declared without a different ownership specifier are assign by default strong by default as of the introduction of ARC, however, the UIKit headers appear to not be using ARC, so this property is most like assign. Note also, since the property is readonly, there is most likely a custom getter in the source, so the ownership specifier in the property doesn't necessarily tell us anything. It's safe to assume that Apple has implemented it in such a way as to avoid retain cycles.
assign is equivalent to __unsafe_unretained, which is a non-zeroing weak reference. This means that it does not retain the object, but will not be set to nil when the object is deallocated. This has higher performance than weak (since it doesn't need to be checked and zeroed), but unsafe, since you could be accessing garbage memory if the referenced object is deallocated.
Also note, the property is declared as readonly, which means it could actually be implemented as a method that returns a private instance variable, or does something else entirely that we don't know about. Basically, all that matters is that you can assume that this property does not retain the object it refers to.
In new code today, you should be using weak instead of assign.

Conversion from weak to unsafe_unretained causes crashes?

I had a library designed for ARC and iOS 5, but a customer wanted to build for iOS 4.x. I converted properties with the weak qualifer to unsafe_unretained, however now it seems I am running into memory corruption-esq crashes.
In the case of the crash, I have a delegate property like this
#property (unsafe_unretained) id<MYDelegateProtocol> delegate;
and I #synthesize the ivar.
whenever I want to call a method on the delegate, I check if it is nil, and if it is not, then I call the method, since I have no optional methods in that protocol, I don't check respondsToSelector.
However, since changing the weak to unsafe_unretained, I have found that apparently the reference goes away, and I am left with a dangling pointer. If I put a breakpoint on ObjC Exceptions, (for unrecognized message), and then po the address of the object, I see that it is an object that is not even implementing the protocol of the delegate, so of course it crashes.
When using unsafe_unretained how can I know that the reference has "gone away"? My code relied on the pointer being zeroed out before.
You have an object ownership problem. An object that has been released won't be nil, it would just be pointing at the address where the object used to be. An nil pointer would point to 0x0. You need to analyze how come your architecture has a delegate that is being released while the record being delegated is alive. On some special circumstances, objects being delegated might retain their delegates (like NSURLConnection). On other cases, objects being delegated are a property of their delegates, in which case, the delegation needs to be cleared out before deallocation. Analyze your pattern and/or provide more information.
Try this class I developed iOSWeakForwarder
When using unsafe_unretained how can I know that the reference has
"gone away"? My code relied on the pointer being zeroed out before.
This has to be determined at compile time by you. Often, the object that is the delegate should set the delegate property of the object delegating to it to nil in the dealloc method. For example:
- (void)dealloc
{
if (_httpRequest.delegate == self)
_httpRequest.delegate = nil;
}
Hope this helps!

Differences between weak and unsafe_unretained

So I had a project that supported iOS 4, so all my IBOutlets were __unsafe_unretained even IBOutlets that were in the nib but outside the controllers main view (Separate View in the same nib) and all worked great.
So the time has come and now the client wants to support only iOS 5 so our team changed all the __unsafe_unretained IBOutlets for __weak IBOutlets but now the IBOutlets that are not inside the main view are set to nil (except in viewdidload) so we are unable to add them later.
If I think about it, it makes sense because if no view (main view) is retaining those IBOutlets they should be deallocated and zeroed (I don't know if that is the correct word), so the solution is to remove the __weak from those IBOutlets
But what doesn't make sense to me is Why the different behavior between unsafe_unretained and weak, in my head the unsafe_unretained ones should be deallocated and when the app tries to access them, they should point to an invalid reference and then the app should crash.
I thought that unsafe__unretained was the same as weak but without the zeroing.
Am I missing something here?
Thanks.
I thought that unsafe__unretained was the same as weak but without the zeroing.
It is, yes.
When Cocoa loads the nib, it creates all the objects autoreleased, so they are still there when viewDidLoad is invoked. However, the autorelease pool has a lifetime that ends when control returns to the run loop. At this point all the objects that aren't owned by anything will go away so any weak outlets will be zeroed at that point.
For most outlets, this is not a problem because objects in the NIB are already generally owned by something anyway. So, for instance, a button in a view is owned by its parent view. Having strong outlets that point to that button are therefore overkill or worse might result in a retain cycle.
Top level objects obviously don't have a parent view to own them so they need to be owned by something else e.g. a controller or "File's Owner". If you are finding stuff disappears, you need to create a strong IBOutlet for it in File's owner.
For more detail, see Apple's docs.
For future searchers who come across this question, I think CRD's Stackoverflow answer to a similar question may explain. Even though the object has been deallocated, the memory that's referenced by the unsafe unretained pointer (which contains the actual object data) is not necessarily zeroed, so things may appear to behave properly until that memory is actually reused/modified/zeroed.
You are correct, the app will crash when trying to access deallocated objects through your stale __unsafe_unretained references.
The reason it doesn't is very likely because the objects are being referenced by some other part of your app with strong references.
Try running with zombies enabled, that should cause an immediate crash when dereferencing the presumedly stale pointers.

Should a UITableViewController's UITableViewCells have strong or weak pointers to its properties?

I have an object myObject in my UITableViewController set as one of its properties which I pass along to a custom UITableViewCell. I "pass it along" by then in turn setting it as a property on the cell. My question is, should this property on the UITableViewCell be weak or strong in iOS 5 using ARC?
I am confused because myObject is owned by the UITableViewController, which owns the UITableViewCell, which in turn has a reference to myObject. But there will never be a case where my UITableViewCell is alive without my UITableViewController being alive (which keeps myObject alive), so is there a need to have a strong pointer from the cell to the object?
I'm just slightly worried about circular references but there shouldn't be one should there?
Probably only your controller should own the object strongly but your cell can retain it, too. It's not a bug.
Your strong references will be a tree, not a circle.

When to use `self` in Objective-C?

It's now more than 5 months that I'm in Objective-C, I've also got my first app published in the App Store, but I still have a doubt about a core functionality of the language.
When am I supposed to use self accessing iVars and when I'm not?
When releasing an outlet you write self.outlet = nil in viewDidUnload, instead in dealloc you write [outlet release]. Why?
When you write self.outlet = nil the method [self setOutlet:nil]; is called. When you write outlet = nil; you access variable outlet directly.
if you use #synthesize outlet; then method setOutlet: is generated automatically and it releases object before assigning new one if you declared property as #property (retain) NSObject outlet;.
Very very important blog to understand about properties getter-setter method in objective c
Understanding your (Objective-C) self
http://useyourloaf.com/blog/2011/2/8/understanding-your-objective-c-self.html
You use self when you are refering to a #property.
Usually it will have been #synthesize'd.
You do not use self if you are refering to a "private" variable. Typically, I use properties for UI elements such as UIButtons or for elements I want easily reachable from other classes.
You can use the #private, #protected modifiers to explicitly enforce visibility. You cannot however use private methods, that do not exist in Objective-C.
The part about nil, release and dealloc is unrelated to the use of "self". You release what you retained, you nil what is autoretained.
You should read the Objective-C guide, it's well written and very enlightening.
You use self. when you're accessing properties of class that you're in (hence self). Basically you use self when you want to retain a value, but is only when you have retain in your property definition.
release just releases object that you've retained. You shouldn't release something that you haven't retained cuz it will lead to crash (zombie object).