Objective-C Library - cannot form weak reference to instance of class - objective-c

I'm currently working with the XMPP Library for Objective-C, and I'm using the "Desktop" example code.
It logs in fine; however, when I open a new chat, or someone sends me a message, it crashes.
This seems like where something goes wrong:
XMPPStream[11678:1b03] RECV:
2012-06-05 15:03:59:379 XMPPStream[11678:1b03] RECV:
2012-06-05 15:03:59:382 XMPPStream[11678:403] RosterController: xmppRosterDidChange:
2012-06-05 15:03:59:387 XMPPStream[11678:403] RosterController: xmppRosterDidChange:
2012-06-05 15:04:01:900 XMPPStream[11678:403] tableView:shouldEditTableColumn:"jid" row:0
2012-06-05 15:04:01:900 XMPPStream[11678:403] user:
objc[11678]: cannot form weak reference to instance (0x7fcd4a498930) of class ChatController
and
objc[11998]: cannot form weak reference to instance (0x7f853bd17c70) of class ChatController
(lldb)
(lldb)
What does "Cannot form weak reference to instance....of class ChatController" mean? Do you guys know how I can fix it? I used an older version of this code with Snow Leopard and it worked, Lion is screwing me up!
Thank you!

Looking at Mike Ash's blog, I found an interesting paragraph:
ARC's implementation of zeroing weak references requires close
coordination between the Objective-C reference counting system and the
zeroing weak reference system. This means that any class which
overrides retain and release can't be the target of a zeroing weak
reference. While this is uncommon, some Cocoa classes, like NSWindow,
suffer from this limitation. Fortunately, if you hit one of these
cases, you will know it immediately, as your program will crash with a
message like this:
objc[2478]: cannot form weak reference to instance (0x10360f000) of class NSWindow
If you really must make a weak reference to classes such as these, you
can use the __unsafe_unretained qualifier in place of __weak.
Did you turn ARC on in your app? If you turn it off, do you get better results?

In my project (as a mistake) there was a weak reference to self in dealloc (it was a separate method, called to clear used resource).
Using weak reference to one property of this object (that captured just a reference to the resource) solved the problem.
It is really strange to create weak reference to half-destroyed object in dealloc.
NEVER WRITE LIKE THIS:
- (void) dealloc
{
[self freeUsedResource];
}
- (void) freeUsedResource
{
__weak MyClass *weakSelf = self;
dispatch_async(self.queue, ^{
[weakSelf.usedResource freeUsedMemory];
});
}

remember that you need to comment two places.
#interface GCDMulticastDelegateNode : NSObject
{
//#if __has_feature(objc_arc_weak)
//__weak id delegate;
//#else
__unsafe_unretained id delegate;
//#endif
dispatch_queue_t delegateQueue;
}
- (id)initWithDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
//#if __has_feature(objc_arc_weak)
//#property (/* atomic */ readwrite, weak) id delegate;
//#else
#property (/* atomic */ readwrite, unsafe_unretained) id delegate;
//#endif
#property (nonatomic, readonly) dispatch_queue_t delegateQueue;
#end

Related

Circular references in Objective-C and clang

Why doesn't the static analyser detect circular references with blocks? I remember it used to do it when I had retains on my delegates instead of assign, pre-blocks introduction. I remember the nice little lines it used to draw on my code (i think...)
If I do this, without using weakSelf, I know I'm going to get a circular reference.
// Note 1: myObject is 'retained' by self.
// Note 2: myObject retains the block for the future
[self.myObject registerBlockOfCodeForFutureExectution:^{
[self doSomething];
}];
Sample Project Exploiting Issue
Now if I know this, and I'm a stupid human, then why doesn't my intelligent computer know this is bad and warn me that I'm being stupid?
There must be a logical reason why it can't detect it, and I want to know what that reason is.
This question is regarding clang and static analysis, please don't suggest how I fix circular references - I know how to do this.
If you use self inside of block it does not automatically mean that you get retain cycle. You get retain cycle only if life-time of block depends on life-time of self object. That may be the case if self has strong reference to myObject or some more complex dependencies are also possible (I assume that it indeed 'saves' block passed to a method, so you already have strong reference there).
So to have retain cycle in your example you need to have two following conditions met (neither of them follows from the code you posted), and compiler needs to be aware of them:
1. Life-time of myObject is tied to self - lets assume that self has strong reference to it
2. saveThisBlockInMyObject: retains block passed to it
I made a small sample that gives compiler warning about capturing self - to address 1st point I declared myObject as a strong property of some class:
#property (strong) MyTestClass* myObj;
...
self.myObj = [MyTestClass new];
For 2nd point I could not find a way to specify that method retains its argument (there're source annotations for returned values, but there's no relevant annotations for method parameters). But you declare block as a strong property of your test class, then compiler is happy to warn you about possible retain cycle:
typedef void (^MyVoidBlock)();
// MyTestClass
#property (nonatomic, copy) MyVoidBlock voidBlock;
self.voidBlock = ^{
[self doSomething]; // Warning!
};
Hope that makes sense :)
The code posted to github does cause a retain cycle.
Current github code:
#interface MyObject ()
#property (nonatomic, copy) dispatch_block_t codeToRunInFuture;
#end
#implementation MyObject
- (void) registerBlockForFuture:(dispatch_block_t)block {
self.codeToRunInFuture = block;
}
// Call in ViewController
self.myObject = [MyObject.alloc init];
[self.myObject registerBlockForFuture:^{
[self runThisInFuture];
}];
I can see where this would be difficult to catch since the Analyzer can not know what block might be and therefore can not tell if there is a self reference either strong or weak. It would have to examine all instances where registerBlockForFuture: is called and the block in each case.
The answer might be to submit a bugreport to Apple.

How do I release properties that are added at runtime in a category?

Given the following category definition how might I handle -dealloc both with and without ARC? I am currently using ARC and to the best of my knowledge and poking around in Instruments, the properties are being cleaned up but I am not 100% confident in that.
#interface NSObject (SuperUsefulThingIWishAllNSObjectsHad)
#property (nonatomic, copy) NSString *foo;
#end
#import <objc/runtime.h>
#implementation NSObject (SuperUsefulThingIWishAllNSObjectsHad)
static const void *MyPropertyKey = &MyPropertyKey;
#dynamic foo;
- (NSString *)foo
{
return objc_getAssociatedObject(self,
MyPropertyKey);
}
- (void)setFoo:(NSString *)foo
{
objc_setAssociatedObject(self,
MyPropertyKey,
foo,
OBJC_ASSOCIATION_COPY);
}
This is more for my own edification but if the solution isn't too hacky I may have some places I actually want to use this.
You don't need to do anything special in dealloc to “clean up” an associated object. The runtime takes care of it for you. This is independent of ARC.
If you're not using ARC, you need to be sure to call [super dealloc] in your own dealloc overrides. But you need to do that regardless of your use of associated objects, and the compiler will warn you if you forget.
UPDATE
In response to your comment: You're right that the Objective-C Runtime Reference doesn't explicitly say the associated object is released (if appropriate based on the association policy) when the main object is deallocated. But that is the only reasonable action, because the point of an associated object is to attach a subordinate object to a main object without changing the main object's source code.
Anyway, the source code of the Objective-C runtime is open source, so we can inspect it to verify that this is indeed what's implemented.
Look at NSObject.mm and you'll see that -[NSObject dealloc] calls _objc_rootDealloc, which calls object_dispose.
The object_dispose function is in objc-runtime-new.mm, and it calls objc_destructInstance, which calls _object_remove_assocations.
The _object_remove_assocations function (yes, it has a typo in the source code) is in objc-references.mm. It removes all objects associated with the object being deallocated, releasing them if appropriate. If you look at objc_removeAssociatedReferences, which is part of the public API and is defined in objc-runtime.m, you 'll see that it also calls _object_remove_assocations.

Why does the Xcode 4.5 static analyzer tell me that I have a potential memory leak when I try to use __attribute__((NSObject))

I have a property that holds a Core Foundation object, specifically a CFHTTPMessageRef. I've tried using the attribute((NSObject)) macro to tell the compiler to treat the referenced object as a normal NSObject and handle the retaining and releasing of that object for me rather than having to CFRelease myself. I've tried changing the property to weak instead of strong, but nothing seems to work, the static analyzer still tells me I have a memory leak, and from the looks of the output from CFGetRetainCount, it would that it's right. Does anyone know why my property would cause a memory leak:
typedef __attribute__((NSObject)) CFHTTPMessageRef HTTPMessageRef;
#interface ABRemoteConnection : NSObject
#property (strong) HTTPMessageRef message;
#end
- (void)dataReceived:(NSNotification *)notification {
self.message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
// do some stuff and if the message is complete, use it and release the
// message object
if (messageIsComplete(self.message)) {
self.message = NULL;
}
}
From the documentation, it looks like __attribute__((NSObject)) is only meant to be used with retain.
But switching strong to retain means you're now adding another ref which the prop is going to manage for you; there's still the original ref that you have to CFRelease.
If you think about it, this makes sense. Imagine doing the same thing with a property(retain) NSObject *:
- (void)dataReceived:(NSNotification *)notification {
self.o = [[NSObject alloc] init];
}
This works fine—but only because ARC sees the alloc and automatically inserts a corresponding release for you at the end of the scope. With a CF___Create function, there's no automatic CFRelease at the end of the scope, so you have to manually write one.
If you really want HTTPMessageRef to be as convenient as, say, NSDictionary, it can't just be a typedef; it has to be a toll-free bridged class.

Why is my object's weak delegate property nil in my unit tests?

I have a pretty simple setup for this unit test. I have a class that has a delegate property:
#interface MyClass : NSObject
...
#property (nonatomic, weak) id<MyDelegateProtocol> connectionDelegate;
...
#end
and I set the delegate in my test:
- (void)testMyMethod_WithDelegate {
id delegate = mockDelegateHelper(); // uses OCMock to create a mock object
[[delegate expect] someMethod];
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], #"should have called someMethod on delegate.");
}
But the delegate is not actually set on line 3 of my unit test, so #someMethod is never called. When I change it to
myClassIvar.connectionDelegate = delegate;
STAssertNotNil(myClassIvar.connectionDelegate, #"delegate should not be nil");
it fails there. I'm using ARC, so my hunch was that the weak property was being deallocated. Sure enough, changing it to strong makes the STAssertNotNil pass. But I don't want to do that with a delegate, and I don't understand why that makes a difference here. From what I've read, all local references in ARC are strong, and STAssertNotNil(delegate) passes. Why is my weak delegate property nil when the same object in a local variable is not?
This is a bug in the iOS runtime. The following discussion has more detail. In a nutshell, the iOS ARC runtime can't seem to handle weak references to proxies. The OSX runtime can.
http://www.mulle-kybernetik.com/forum/viewtopic.php?f=4&t=252
As far as I understand from the discussion a bug report has been filed with Apple. If anyone has a sensible idea for a workaround...
I don't really know what's happening here, but OCMock returns an autoreleased NSProxy-descendant from the mockForProtocol: method, which I think is right. Maybe ARC has problems with NSProxies? Anyway, I've overcome this problem by declaring the variable __weak:
- (void)testMyMethod_WithDelegate {
// maybe you'll also need this modifier inside the helper
__weak id delegate = mockDelegateHelper();
...
It really doesn't need to be __strong (the default) in this case, as it's autoreleased and you're not keeping it around...
A workaround is to use Partial Mocks.
#interface TestMyDelegateProtocolDelegate : NSObject <MyDelegateProtocol>
#end
#implementation TestMyDelegateProtocolDelegate
- (void)someMethod {}
#end
#implementation SomeTest {
- (void)testMyMethod_WithDelegate {
id<MyDelegateProtocol> delegate = [[TestMyDelegateProtocolDelegate] alloc] init];
id delegateMock = [OCMockObject partialMockForObject:delegate]
[[[delegateMock expect] someMethod]
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], #"should have called someMethod on delegate.");
}
#end
I am no ARC expert but my guess is that mockDelegateHelper() is returning a weak object. As a result delegate is nil before the second line of code executes. I would venture to guess that either the mockDelegateHelper() is the culprit or that OCMock is getting in the way with how it manipulates and creates objects.

Why alias a new name and explicitly release the IBOutlet property?

Recently some example from Apple looks something like this:
#interface ViewController : UIViewController
{
**// Notice no more ivar here.**
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
#implementation ViewController
#synthesize webView = _webView;
...
- (void)dealloc
{
[_webView release];
[super dealloc];
}
My question is why aliasing the webView to _webView, and release in the dealloc since there is no ivar named _webView?
One more question, if I declare a property that has no related ivar, do I need to release it in dealloc?
When you #synthesize a property that doesn't have an associated ivar (whether you say #synthesize property or #synthesize property=_property), an ivar is generated for you. The default is to use the same name for the ivar as the property itself. If the property is a retain property, then you have to release the object in -dealloc or you'll have a memory leak.
Apple's convention is to name ivars (whether declared explicitly in the interface or implicitly in an #synthesize) with an underbar to indicate the private nature of the ivar. IMO it's also helpful to ensure that people use the ivar only when they intend to (since for some coders it seems to be easy to accidentally type myproperty when you mean self.myproperty, which can create significant bugs).
The answer to your last question is basically yes, though technically the answer is 'sometimes'. You only have to release the object if there is an object stored in an ivar that was retained. That's most of the time. However, properties are just a shortcut for invoking methods named 'myproperty' and 'setMyproperty' (etc), so it's possible to have a pair of methods with those names and an associated property that doesn't actually have an ivar paired with it. But if you're declaring properties with the retain attribute and synthesizing them, you should always release the objects their ivars point to.
I think Use of properties by Xcode 4 templates will explain this better and more in detail than I could.