Reason for declaring a property as (strong, strong) - objective-c

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..

Related

Xcode warning if using "assign" attribute for reference types (objects)

Is there an Xcode warning, or any kind of way to get a warning, when one declares an object (reference type) property using the assign attribute in ARC:
#property (nonatomic, assign) NSNumber *myNumber;
I converted a long property to NSNumber and accidentally forgot to change the attribute from assign to strong.
There are no compile-time warnings or errors, and the run-time error that one would get would only happen sometimes and it is a very obscure crash. Only while debugging is when one would get a crash and an error like "message sent to a deallocated instance" and that's because of the use of zombie objects in development.
For non-debug builds, the crash doesn't happen often and it is reported (by Crashlytics, for example) as EXC_BAD_ACCESS - KERN_INVALID_ADDRESS. I'm assuming that the crash is caused by this issue.
I understand that assign is a valid option for an object if you want to maintain a weak reference to it, and you don't want the pointer to automatically become NULL when the object gets deallocated. However, I imagine there should be a warning one can turn on or off because assign is not something you normally want to use in ARC, but I can't find it in the build settings.
Unfortunately, I couldn't find any warning flag for that. It would be a cool thing to have though. You can refer to this site for a list of all clang warnings you can enable in Xcode.
This is not technically an answer to my question because my question asks whether there is a setting to enable warning and the answer to that is "no" as per the accepted answer.
However, if you want to find such cases, you can do a global search using regular expression. You have to switch the find options to "Regular Expression".
To find something like
#property (nonatomic, assign) NSNumber* ...
you can use the regex
assign\) [a-zA-Z]+\*
You can play around with it. For example, if you put a space between the type and the asterisk in your property declaration like this
#property (nonatomic, assign) NSNumber * ...
you just need to add a space before the slash that escapes the asterisk like this
assign\) [a-zA-Z]+ \*

When should I declare an instance variable rather than property in the header? [duplicate]

This question already has answers here:
Do declared properties require a corresponding instance variable?
(6 answers)
Closed 8 years ago.
For example, in the following codes.
#interface TUTViewController : UIViewController
{
NSTimer *timer;
}
#end
and
#interface TUTViewController : UIViewController
#property (weak, nonatomic) NSTimer *timer;
#end
In which scenario do we use the first method to declare variable?
You are going to get lots of opinions on this, often stated as hard fast rules.
Example:
Maddy: Never put ivars in the .h. ivars should always be private
meaning they do not belong in the public .h. If you create ivars, put
them in the .m file
I have tremendous respect for Maddy, but I disagree with him on this one.
If you put your iVars in your .m file, they are hidden from other classes, but they are also hidden from subclasses that you create.
I prefer to mark my instance variables as #protected, which makes them available to subclasses, but not to other classes.
Others will tell you to make EVERYTHING a property. Before ARC, it made sense to save all your objects in properties, since you could use the setter on the property to manage the memory on your objects. (When assigning a value to a retained property, the setter would first release any old value, then retain the new value.) Now ARC takes care of that for you even for iVars, so the argument for making everything a property is less.
What I do is to make everything an iVar, unless:
I need a custom getter or setter method with special behavior.
I want to access the value from another object.
I need to mark a property as "atomic" for access from another thread. (get in the habit of declaring all of your properties as "nonatomic." If you don't know what atomic is for for, you want nonatomic. Atomic properties are slower than nonatomic.)
As a matter of policy I NEVER access another object's iVars except trough a property.
There is a small but real amount of overhead in using a property rather than an instance variable. A property read/write always makes a method call. An iVar accesses the memory directly without the overhead of a method call. Usually the difference is too small to matter. But, if you're doing millions of operations, like doing something to every pixel in a large image, or handling callbacks from processing video or audio samples in real-time, the difference can be large.
I would highly suggest to use #properties unless there is a very good reason not to. It's true the discussion is a religious one more than a technical one but since we are probably all followers of the Cult of Mac, if Apple prefers you to use #properties then that's the standard. In my opinion both Apple documentation and Xcode aren't as pushy on standards like ReSharper would do in Visual Studio for instance (it warns when you don't use var for example). That's a pity because that would make it easier for me to pick up code after somebody else.
There is a way to "hide" #properties in a .m file, you should declare it as follows:
#interface ABCMySpiffyClass ()
#property (weak, nonatomic) IBOutlet UIImageView *spiffyImage;
#property (weak, nonatomic) IBOutlet UILabel *spiffyTitle;
#end
These are not completely private to another consumer of your class but it is hidden at first sight. This should tell the other developer that he or she should not use them. I think public/private has more to do with documentation as it has to do with application security for most apps.

Why do I declare properties twice? or do I?

Sorry for the kind of useless post title, but since I'm not really sure what I am doing, that was the best i could come up with.
In my header file it looks like this
#interface RootViewController : UITableViewController {
NSMutableArray *eventsArray;
}
#property (nonatomic, retain) NSMutableArray *eventsArray;
#end
This is not all the properties but i removed all but one for simplicity.
I'm doing this by following a guide from apple developer. It seems as though the guide is not totally updated since it tells me to synthesize properties, wich i should not have to anymore right?
Anyways, why is it like this? To me, a beginner at this, it seems as though I declare the property twice? Or do I do something else at the first row there?
It's like this for historical reasons, with the older compiler.
You can do this nowadays:
#interface RootViewController : UITableViewController
#property (nonatomic, retain) NSMutableArray *eventsArray;
#end
The way you have it, you are declaring an instance attribute, and then you are saying you want to automatically generate getters and setters.
Nowadays, you can just say you have a property and the compiler will automatically generate the instance attribute at compile time. It removes the apparent redundancy.
To me, a beginner at this, it seems as though I declare the property
twice? Or do I do something else at the first row there?
A property and the instance variable that backs it up (if there is one) are two different things. A property is really just a promise that the class provides certain accessor methods. So the fact that you had to declare the property and ivar separately isn't strange. However, most properties are, in fact, backed by an ivar with a related name, and writing and maintaining the two separately got to be a chore. So Apple added ivar synthesis to the compiler, so that the compiler generates an ivar for any synthesized properties for which an ivar doesn't already exist. Also, because synthesized accessors are by far the most common, and because the compiler will use any accessors that you provide even if a property is marked #synthesize, that became the default so that you no longer need the compiler directive.

'assign' and 'weak' are mutually exclusive

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.

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.)