'assign' and 'weak' are mutually exclusive - objective-c

I am trying TwitPic to post Image with Text over Twitter using GSTwitPicEngine class, which use YAJLiOS,
So i add YAJLiOS framework in my project and, i am getting this('assign' and 'weak' are mutually exclusive) error in the file "YAJLParser.h" that is in YAJLiOS framework.
showing Error in the following line-
#property (assign, nonatomic) __weak id <YAJLParserDelegate> delegate;
When i remove the __weak it becomes Apple Mach-O Linker (Id) Error.
Please help.How to handle this kinda errors.I am not getting the reason.

silly me ...
try
#property (unsafe_unretained, nonatomic) id <YAJLParserDelegate> delegate;

Probably you figured it out by now,
anyways here is how I got rid of this error:
#property (assign) __unsafe_unretained id<YAJLParserDelegate> delegate;
Make sure all other declarations of delegate in your .h code (if any) are __unsafe_unretained e.g. in #private section:
__unsafe_unretained id<YAJLParserDelegate> delegate;

As you probably already know, assign and weak are NOT the same thing ... functionally they're very close, but weak is much more sophisticated and rather cleverly nulls out references to disposed objects to avoid crashes ( amongst other things vis retain cycles ).
Regardless - what to do? My best guess is to try pulling out ARC's backward compatibility legacy fix ... replace _weak with _unsafe_unretained and see how that goes.

Related

Reason for declaring a property as (strong, strong)

I just got a large chunk of code that someone else have written. First I dismissed it as a typo but then noticed it in several other places as well.
The essentials is that the other programmer (not sure of his "skill level") declared some properties as
#property (strong, strong) NSObject *anObject;
The compiler does not complain so I was wondering if there is any reason for doing this or should I consider them all to be "typos"?
(The project uses ARC)
I see no sense in doing so and am surprised that the compiler does not complain about that.
I think the developer miswrote it. Strong keyword increases the retain count by 1 so by 2 strongs maybe the dev thought to increase retain count by 2..

Better Understanding Property Declarations

I want to show you an example of one of my header files and get your suggestions on what I could do better giving the situations below.
ARC is enabled
#property (nonatomic, assign) int some_simple_value;
#property (nonatomic, strong) NSMutableArray *someArray;
#property (nonatomic, weak) IBOutlet UIButton *someButton;
#property (nonatomic, copy) NSMutableArray *someArrayCopy
#property BOOL some_bool;
I understand what a lot of the types mean, but I don't know why I would use a given one instead of another in some cases. Also, if I know my object is only accessed by one class, should I not use nonatomic (because there's no worry of multiple threads accessing it, right?)
ANSWER
These answers helped me drastically:
What's the difference between the atomic and nonatomic attributes?
and
Objective-C declared #property attributes (nonatomic, copy, strong, weak)
Well, you could read the documentation! :) But if you want a perhaps more friendly instructive explanation, I've written you one:
http://www.apeth.com/iOSBook/ch12.html#_properties_2
However, before you read that, you should really read about memory management, earlier in that chapter:
http://www.apeth.com/iOSBook/ch12.html#_memory_management
strong and weak are very different indeed; if you understand memory management and ARC, you'll know why.

How to declare a weak reference in iOS 3.1.2

My app must support iOS 3.1.2
But it looks like __weak, __block and __unsafe_unretained are only for newer versions of iOS
Can someone show me an example of how to declare a weak reference in for iOS 3.1.2?
Should I just do:
#interface foo
{
SomeType* _bar
}
#property (nonatomic, assign) Sometype* bar;
#end
#implementation
#synthesize bar = _bar;
#end
Assign, as you have used it, is the same as unsafe_unretained.
As you noted, you cannot declare something as weak before iOS5 (which cleans up a reference for you).
So basically when you are using an assign reference just be careful to clear out any assign references when the object is slated to go away.
At this point there is no value in supporting iOS 3.x. You should convince whoever you are working for to move away from it, if only to use ARC. It will make lots of memory issues and potential crashes go away.

#synthesize ivarName = _ivarName convention, preference or performance? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Synthesized property and variable with underscore prefix: what does this mean?
The usage of Objective-C properties has always felt awkward to me. It's one of the "I know how to use them, but I'm not always sure why I'm using them." kind of things and recently I've been seeing a lot of this:
// in .h file
#interface MyObject : NSObject
{
id _coolIvar;
}
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;// <- whats the point of that.
#end
So what is the point of declaring an ivar with an underscore and then using #synthesize to access it, Opposed to just declaring the #property with the same name as the ivar?
Side Question:
I've noticed that this convention has been becoming increasingly more popular since blocks started becoming the preferred approach for async callbacks opposed to the target/selector approach. Is that a coincidence or does the above #property declaration convention play nicer with block scopes?
It's preference.
It's also my preference to not declare the variables twice and just let them be synthesized like:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
The two reasons I like to use the _ prefix is
I know when I am going through an accessor and when I am accessing the variable straight.
If it makes sense for me to call an ivar address it is more than likely that inside a method a similar variable would also be logically called address. If my ivar does not have an _ prefix then my local address will mask the ivar address.
I also like how xcode will autocomplete vaiables starting with an _ when you start typing your #synthesize myVar = _...
NB
You may run into the odd name clash (I have only once) but the warning that the complier gives you makes it a pretty easy spot and simply changing the name is a quick win.
#isaac touched on not declaring ivars so that they are not publicly advertised but does not explain how/why. Basically you can declare #property's in a class extension to still give you the benefits of the #synthesized getter/setter but without making your public API look ugly.
Your previous example would look like this (if you wanted coolIvar to not be publicaly advertised):
// in .h file
#interface MyObject : NSObject
#end
// in .m file
#interface MyObject () <-- Like a category but with no name
#property (assign) id coolIvar;
#end
#implementation
#synthesize coolIvar = _coolIvar;
#end
I use the _ivar construct to make sure that I don't access the ivar directly (by mistake) when I really intend to go through the accessors.
With the modern runtime (iPhone applications and 64-bit programs on Mac OS X v10.5 and later) the ivar declaration is no longer required. So your code is reduced to:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
Per #Monolo's answer, the _ivar is a good failsafe to make sure you don't inadvertently access the ivar directly. Remember, the #property and #synthesize is there to replace boilerplate code - without it you'd have to code getter and setter accessors.
There are a couple benefits to differentiating ivars from property accessors.
One is described by Monolo - it prevents mistakingly accessing an ivar when what you intended to access was a property.
Another is that in theory it guards against collisions - cases where you might name an ivar identically to another ivar that's beyond your implementation (ie, a superclass ivar name).
There are different thoughts on best practices, but lately I've read in several places I consider reliable that the best practice is actually to no longer to declare ivars at all in your interfaces (ivars are created implicitly via the property declaration).
Some people don't like "implicit" - but there are material benefits: Not declaring them avoids advertising ivars that aren't really public. It also goes even further in avoiding collisions - because in theory when a property is synthesized and the ivar generated, it will do so without introducing a convention that may itself collide with a private ivar naming convention (as may be the case with preceding or trailing underscore).
Preference. Some people like to prefix instance variables with a underscore (so one can easily tell if one is referencing a ivar, or a variable in a more local scope), and some don't.

EXC_BAD_INSTRUCTION when synthesizing #property (weak) IBOutlet NSWindow *window

I'm a newbie to ObjC/Cocoa and Mac development in general, and toying with the basics.
The simplistic default template for a new Cocoa application in Xcode 4.2 on Lion looks like this:
// AppDelegate.h
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#end
// Appdelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
#end
I've been using that as a basis for various experiments. Reading up on Automatic Reference Counting (which the project is set to use)—this article, for example—I assumed that one could, perhaps even should replace the assign qualifier for NSWindow *window with weak, but that does not seem to be the case.
The app builds fine, but hangs during startup, with Thread 1: Program received signal: "EXC_BAD_INSTRUCTION" in AppDelegate.m on the line with #synthesize window = _window;.
Changing the qualifier to strong makes the program work, but I fail to see how it would make sense to go from assign to strong. I'd gotten the impression that the pairings for non-ARC/ARC are assign/weak and retain/strong.
A more experienced coder friend suggested that even if the weak qualifier causes window to be prematurely deallocated and some access attempt on it to fail, the exception should be EXC_BAD_ACCESS, not EXC_BAD_INSTRUCTION.
I'm obviously missing something here, but I have no idea what.
EDIT: After a closer look at the crash-time gdb output, the same friend pointed me to this article by Mike Ash that sheds some light on this. Due to reasons beyond my understanding, NSWindow and some other classes that override retain and release can't be the target of zeroing weak references. Interestingly, changing the property declaration to this works:
#property (unsafe_unretained) IBOutlet NSWindow *window;
...even though unsafe_unretained isn't mentioned in Apple's documentation for Declared Properties.
With that, a REVISED QUESTION:
What would be the proper way to go here? Stick to assign despite mentions around the web that it shouldn't be used with ARC? Go for strong? Keep using unsafe_unretained since it seems to work? Something else?
Conceptually, 'weak' is the correct qualifier for a top-level IBOutlet on OS X (iOS is another story). However, to create a proper weak reference that zeroes on deallocation requires cooperation from the Objective C runtime. Classes that override retain or release break this support and so you can't create a weak reference to them. UIWindow is one such class.
That's why the template uses 'assign'. Perhaps it should really use the synonym 'unsafe_unretained' if ARC is enabled. In either case you have a simple weak reference that is not zeroed.
Mike Ash's blog discusses the issue with some Cocoa classes.
Look for it in the middle part of the page: Friday Q&A ARC. Look/Search for the text that starts with "ARC's implementation of zeroing weak references..."
The problem is that some classes don't handle the zeroing weak references that __weak brings. The solution is to go with what the normal ARC templates provide assign.
Well, to answer the second question, even Apple's templates use assign for window when using ARC. So you may be safe for now. But your mileage may vary in the future.
Mike Ash has a very good explanation of what's going wrong here (search for "ARC's implementation"). The gist of it is that the NSWindow class specifically does not support weak referencing: apparently because it relies on overriding retain and release with its own implementations.
I expect there's a few more such gotchas scattered through the legacy Cocoa classes, and these don't appear to be documented yet - instead, you find out through a runtime error. (I expect this will become a compiler warning as well at some point.)