Why won't my delegate accept performSelectorOnMainThread:withObject:waitUntilDone:? [duplicate] - objective-c

This question already has answers here:
Compiler gives warning on performSelectorOnMainThread:#selector(delegateMethod)
(4 answers)
Closed 10 years ago.
Xcode 4 is giving me compiler warnings on the performSelectorOnMainThread:withObject:waitUntilDone: message sent to my delegate and I don't get it.
My delegate is declared like:
#property (nonatomic, assign) id <AccountFeedbackDelegate> delegate;
And then eventually executed on the main thread:
[self.delegate performSelectorOnMainThread:#selector(didChangeCloudStatus) withObject:nil waitUntilDone:NO];
Yet Xcode persists on giving me:
warning: Semantic Issue: Method '-performSelectorOnMainThread:withObject:waitUntilDone:' not found (return type defaults to 'id')
Of course the code compiles and runs fine, but I don't like the warning. When I redeclare the delegate like this, the warning vanishes, but I don't like the workaround:
#property (nonatomic, assign) NSObject <AccountFeedbackDelegate> *delegate;
What am I missing? What did I do wrong?
Cheers,
EP

performSelectorOnMainThread:withObject:waitUntilDone: is declared in a category on NSObject in NSThread.h. Since your variable is of type id, the compiler cannot be certain that it can respond to a message defined for NSObject. And unlike with plain id variables, the compiler warns you about this when your variable is declared id <SomeProtocol>.
So you should indeed declare your delegate as NSObject <AccountFeedbackDelegate>.
PS: The "standard" way to get rid of this kind of warning by declaring the protocol as #protocol AccountFeedbackDelegate <NSObject> won't work here because performSelectorOnMainThread:withObject:waitUntilDone: is not declared in the NSObject protocol.

Related

Old Objective c code assign __weak

In the old code of objective c
there are some .h file that have #property declare as follow:
#property (nonatomic, assign) __weak XXXObject *state
Since in later iOS version, this code is no longer valid and in XCode 8.3.3,
following exception thrown and the program can't build:
Unsafe_unretained property 'state' may not also be declared __weak
May i ask what is the behavior of the old code for declaring both assign and __Weak, and in order to solve the exception thrown, what's the best way to change the declaration of the property?

When to synthesize objective [duplicate]

This question already has answers here:
When should I use #synthesize explicitly?
(7 answers)
Closed 8 years ago.
I am having some difficulty understanding what objects are supposed to be synthesized. For example:
#interface DoSomething : UIView
#property (strong, nonatomic) UIColor *frameColor;
#property BOOL toggleScrollability;
- (void) changeBackgroundColorOfView;
#end
In the .m file, which of these three items should be synthesized? Is there any disadvantage if I try and synthesize them all? In general, what is the rule of thumb for what objects you are supposed to synthesize?
The first two are properties; the third is an instance method. #synthesize applies only to properties.
However, if you're building for iOS 6 or newer, you don't need to synthesize at all. The compiler has handled this automatically for the last few years now.
You can only synthesize properties, so you won't be able to write #synthesize changeBackgroundColorOfView.
Since XCode 4 I think, you don't have to use #synthesize anymore. The compiler automatically add it when it needs to be and you can access it by adding a _ before the name of your property.
In your example, you will access the frameColor property as _frameColor if you are in the DoSomething class, doSomethingInstance.frameColor if not.
But, you can always add it yourself if you want to rename your property for internal stuff.
See Apple's reference.

Under what conditions is #synthesize automatic in Objective-c?

Under what conditions is #synthesize automatic in Objective-c?
Perhaps when using LLVM 3.0 and up? From reading around the net it seems like #synthesize is unnecessary starting with Xcode 4. However I'm using Xcode 4 and receiving warnings when I don't #synthesize a property.
Some of the responses to Why don't properties get automatically synthesized seem to imply #synthesize can be omitted at some point under some circumstances.
Another (old) reference hinting that #synthesize might be automatic at some point in the future.
As of clang 3.2 (circa February 2012), "default synthesis" (or "auto property synthesis") of Objective-C properties is provided by default. It's essentially as described in the blog post you originally read: http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/ (except that that post describes the feature as "enabled, then disabled"; I don't know if that's an issue with Xcode or if the clang developers themselves have gone back and forth on the question).
As far as I know, the only case in which properties will not be default-synthesized in clang 3.2 is when those properties have been inherited from a protocol. Here's an example:
#import <Foundation/Foundation.h>
#protocol P
#property int finicky;
#end
#interface A : NSObject <P>
#property int easygoing;
#end
#implementation A
#end
int main() { A *a = [A new]; a.easygoing = 0; a.finicky = 1; }
If you compile this example, you'll get a warning:
test.m:11:17: warning: auto property synthesis will not synthesize property
declared in a protocol [-Wobjc-protocol-property-synthesis]
#implementation A
^
test.m:4:15: note: property declared here
#property int finicky;
^
1 warning generated.
and if you run it, you'll get an error from the runtime:
objc[45820]: A: Does not recognize selector forward:: (while forwarding setFinicky:)
Illegal instruction: 4
As of Xcode 4.4, if you don't write #synthesize or #dynamic for a property. the compiler acts as though you had written #synthesize property = _property.
Prior to Xcode 4.4, you must do one of the following things for each property or else the compiler will issue a warning and you will get a runtime error. In Xcode 4.4 or later, you may do any of the following things instead of letting the compiler automatically synthesize the property accessors and instance variable.
Use the #synthesize directive.
Use the #dynamic directive and somehow provide the property getter and (if necessary) setter at runtime.
Explicitly write the property getter method and, if the property is readwrite, the property setter method.
Note that you can use the #synthesize directive (or the #dynamic directive) and also explicitly provide the getter and/or setter methods. But #synthesize provides them if you omit them.
From the New Features in Xcode 4.4 document:
Objective-C #properties are synthesized by default when not explicitly implemented.
So #synthesize is automatic by default starting from Xcode 4.4 with the LLVM 4.0 Compiler.
Also, synthesize will not be automatic if you have implemented the setter AND getter manually. So if you wonder why you can't access _someVariable, having declared #property (...) SomeType someVariable, then it is because you have implemented the setSomeVariable: and someVariable methods.
You can turn off the synthesize warnings by clicking on the project name in the Project Navigator on the left then click All Cobined in Build Settings and then search for synthesize. That should be set to No.

Since when is it possible to declare Objective-C 2.0 properties in a category?

I always thought that one cannot declare an object property in a category.
Until my partner did it in our app's code, and it seemed to work.
I went on a SO and Google binge to try to explain to him that no, Objective-C categories can only be used to add methods, not properties. I found questions such as:
Setting New Property In Category Interface Implementation (look at the accepted answer)
Can I add a property for a method not in my category?
But then I found this link on Apple's site that contains the following about the #property declaration:
A property declaration begins with the
keyword #property. #property can
appear anywhere in the method
declaration list found in the
#interface of a class. #property can
also appear in the declaration of a
protocol or category. (emphasis added)
I know that this doesn't work:
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
But this compiles:
#interface MyClass ()
#property NSInteger foobar;
- (void) someCategorizedMethod;
#end
My question is (a) what's the best practice here? and (b) is this something that is new to Objective-C 2.0, and instead of using a "real" iVar, it simply uses associative storage behind the scenes to make this work?
You have always been able to declare an #property in a category. What you couldn't do -- and still can't -- is declare storage for the property in the category, neither as an instance variable nor via `#synthesize.
However....
#interface MyClass () is not a category. It is a class extension and has a distinctly more specific role than a category.
Namely, a class extension can be used to extend a class's #interface, and this includes #properties that can be #synthesized (including synthesizing storage in the modern runtime).
Foo.h:
#interface Foo
#end
Foo.m:
#interface Foo()
#property int x;
#end
#implementation Foo
#synthesize x; // synthesizes methods & storage
#end
it simply uses associative storage
behind the scenes to make this work?
Nope -- it is a real instance variable. The modern runtime fixes the fragile base class problem.
#interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
#end
The above doesn't work (as expected) because foobar is, effectively, a global variable.
If you change it to:
#interface MyClass () {
NSInteger foobar;
}
- (void) someCategorizedMethod;
#end
Then it'll work with the latest release of the llvm compiler (with the right flags, as #Joshua indicated in a comment).
Generally speaking, properties are nothing different from other methods. As long as the ivar used is available in the ordinary class, there is no problem at all. It's just syntactic sugar.
Things start to get more difficult if also the ivar is automatically created, as is possible in some configurations.
The main point here is that declaration of the ivar is independent from the property.
Assotiative storage is the solution.
Have a look at this post.

Synthesize in Objective C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
#property #synthesize
Explain the working or purpose of synthesize
Basically, #synthesize automatically generates the getters and setters based on the #property declaration.
synthesize used with property.When you declair a property in .h file then you need to synthesize that in .m file.
#synthesize creates getter and setter for your property.If you do not synthesize the property then you can use property.(it gives crash).
var=self.yourProperty (calling getter). simmiler to var=[self getYourProperty];
self.yourProperty=var (calling setter). simmiler to [self setYourProperty:var];
without synthesize you cant use the setter and getter.