Consider:
typedef void (^select_block_t)(UIView *) ;
(1) #property (copy, nonatomic) select_block_t myBlockProperty ;
(2) #property (strong, nonatomic) select_block_t myBlockProperty ;
(3) #property (assign, nonatomic) select_block_t myBlockProperty ;
and:
(A) self.myBlockProperty = ^(UIView *) {NSLog(#"Hi");} ;
(B) self.myBlockProperty = [^(UIView *) {NSLog(#"Hi");} copy] ;
I am trying to understand what is the correct way to map which property declaration with which block copy semantics
I have seen examples here on S.O. that would favor[1:B]
But then I get confused by how redundant the 'copy' operation is.
My limited understanding is that [1:A] should be correct, because I want
the block to be copied once when I assign the property, not once at block creation and then once again at property assignment time.
[3:B] would also make sense according to my rationale. So, what am I misunderstanding?
[1:A] is correct, yes. [3:B] is incorrect because:
it's not clear that the class owns the property, so should release it in dealloc (but it should)
the setter (B) looks like a leak, and the static analyser might flag it as such, because the block is copied, handed to a property, then leaves the scope with retain count +1.
using (3) means that it only works if you set a heap-block (a copied block) with a retain count of one. This leaves plenty of margin for error when using the property. (1) works with both stack-blocks and heap-blocks, and will also correctly retain auto-released blocks.
EDIT: I see you're using ARC. In that case, it's not possible to use [3:B] at all. The compiler will release an object (even when copyed) once it's out of scope, and this property setter won't have retained it. Therefore the property will contain a bad pointer, it's an EXC_BAD_ACCESS waiting to happen.
Related
I have a property defined like this:
#property (nonatomic, retain) MyClass *someObject;
I'm currently using this assignment statement:
someObject = [[MyClass alloc] init];
In terms of memory managment is the above assignment statement equivalent to:
self.someObject = [[[MyClass alloc] init] autorelease];
Assume #synthesize someObject; is in the #implementation section. Also I'm not using ARC.
Note: The following is based on the EDITED version of the original post, where "assign" has been replaced with "retain" ---
Yes, the two are "equivalent", in that they will both result in leaving the MyClass object (properly) retained with a retain count of 1 in the property. The second version goes through some extra work, which may or may not be an issue, depending on how performance-sensitive you are.
Some people argue you should never use the property reference (ie, self.propname) from within the class, but instead reference the instance variable, especially for initialization and deallocation. Others argue just the opposite. I generally favor always using the property reference, except during initialization where (as in this case) using it might result in an extraneous retain/autorelease.
Using Xcode 4.2 and ARC, I notice that the auto-generated code for an NSManagedObject still reads like this for properties:
#property (nonatomic, retain) NSString * someString;
1) Shouldn't retain now be replace with strong or weak?
2) Why does the auto-generated code still use retain
3) What is the correct replacement for retain in this property statement?
I'm currently debugging a problem using NSFetchRequest, and I thought this might be the source of the problem. Thoughts?
1) Shouldn't retain now be replace with strong or weak?
No. You cannot replace retain with weak; they are different. And strong is a 100% synonym for retain; they are identical. You can use either, so there is no "should" here. You can replace retain with strong if you like, but you don't have to.
2) Why does the auto-generated code still use retain
Why not? See (1). retain is correct so there is no problem.
3) What is the correct replacement for retain in this property statement?
There is no need to replace retain.
I'm currently debugging a problem using NSFetchRequest, and I thought this might be the source of the problem. Thoughts?
It isn't.
To answer all three questions in one: retain and strong are synonymous with each other, so both are correct. The documentation states
retain implies __strong ownership
strong implies __strong ownership
Before ARC, you have to 'release' an object which is retained. That mean retain has counter part. After ARC you don't need to release. So use strong. Its a visual clue that you don't need to call release.
"retain" is equals to "strong".
"strong" is used for example:
#property (nonatomic, strong) NSString * someString;
And "__strong" is used for example:
-(void) someMethod
{
__strong NSString* vStr = [[NSString alloc] initWithString:#"some string"];
}
On Apple Docs. says:
Property Attributes
The keywords weak and strong are introduced as new declared property attributes, as shown in the following examples.
// The following declaration is a synonym for: #property(retain) MyClass *myObject;
property(strong) MyClass *myObject;
Apple doc. http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
Well ! I got confused about the way of declaring variables & implementing its properties.
The .h File contents
#interface XYZAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet XYZViewController *viewController;
#end
The .m File Contents
#import "XYZAppDelegate.h"
#import "XYZViewController.h"
#implementation XYZAppDelegate
#synthesize window=_window;
#synthesize viewController=_viewController;
My questions/Queries are as follows.
Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
What are the additional features other than this ? ( In coding specific )
Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
You do not have to declare the
variable. It is done automatically,
I believe by #synthesize. One
advantage to declaring it is that the
debugger will automatically list it.
Weigh this against the ugliness of
redundant definition.
Other features: read only properties,
assigned (unretained) values.
The underscore is a convention for
naming member variables that are
differently named than properties and
method variables. Apple's samples
sometimes use this convention and
sometimes do not. I view it as
usually unnecessarily verbose as a
programmer can easily tell the
difference between myVariable and
self.myVariable.
1) Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
No. You aren't required to declare variables for the corresponding properties. You are required to use the #synthesize propertyName command which tells the compiler to create those variables for you.
2) Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
Most people (all?) have been stung by memory management nightmares. Some of these are caused by sloppy/lazy/zero-sleep coding. Using #synthesize propertyName = _propertyName allows the programmer to immediately know that the underscored variable is private to the class, and is unretained. It prevents issues where you specifically allocate or copy an object to store in the property, or accidentally assign an autoreleased object to the ivar.
Consider:
1) An autoreleased object being assigned to an unretained ivar.
#synthesize propertyName;
propertyName = [NSString stringWithFormat:#"I've just made %#", "a boo-boo."];
"propertyName" now references an object that will soon not exist, which will create EXEC_BAD_ACCESS errors down the road (as soon as it's referenced again).
2) A retained object being set to the retained property.
#synthesize propertyName;
self.propertyName = [[NSString alloc] initWithFormat:#"I just created %#", #"a leak"]
Now we've created an NSString object, and set it to the propertyName property, which itself is retaining the variable. Now the object is double retained and won't be properly released.
Both of these issues are easy to combat (even when tired, albeit less so) when you properly name your ivars with an underscore. It's not a fool-proof method, but it makes it considerably easier to manage the retain counts of objects in your head.
(1) No, not with the new 64-bit only features. The variables are declared for you, automatically.
(2) I don't know what you're asking here.
(3) It's just a convention, so that the variable name is different from the accessor name. Makes it clearer which you're dealing with.
I'm currently using the iOS 5 SDK trying to develop my app.
I'm trying to make an NSString a property, and then to synthesize it in the .m file (I have done this before with no issues). Now, I came across this: "Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects."
This is my code:
.h
#interface ViewController : UIViewController {
NSString *newTitle;
}
#property (strong, nonatomic) NSString *newTitle;
.m
#synthesize newTitle;
Does anyone have a clue how I could fix this?
Thanks!!
My guess is that the compiler version you’re using follows the memory management rules for declared properties, too — more specifically, for declared properties’ accessors:
You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”.
A property named newTitle, when synthesised, yields a method called -newTitle, hence the warning/error. -newTitle is supposed to be a getter method for the newTitle property, however naming conventions state that a method whose name begins with new returns an object that’s owned by the caller, which is not the case of getter methods.
You can solve this by:
Renaming that property:
#property (strong, nonatomic) NSString *theNewTitle;
Keeping the property name and specifying a getter name that doesn’t begin with one of the special method name prefixes:
#property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
Keeping both the property name and the getter name, and telling the compiler that, even though the getter name starts with new, it belongs to the none method family as opposed to the new method family:
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang compilers
#endif
#if __has_attribute(objc_method_family)
#define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
#else
#define BV_OBJC_METHOD_FAMILY_NONE
#endif
#interface ViewController : UIViewController
#property (strong, nonatomic) NSString *newTitle;
- (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
#end
Note that even though this solution allows you to keep newTitle as both the property name and the getter name, having a method called -newTitle that doesn’t return an object owned by the caller can be confusing for other people reading your code.
For the record, Apple have published Transitioning to ARC Release Notes, in which they state:
You cannot give a property a name that begins with new or copy.
They’ve already been notified that their statement is not quite accurate: the culprit is the getter method name, not the property name.
Edit 17 Jan 2015: I’ve just noticed a recent commit to Clang that suggests option 3 above (using objc_method_family(none)), including a fix-it, for the general case where a property name matches one of the special method family prefixes. Xcode will likely incorporate this change eventually.
Unacceptable Object Names
newButton
copyLabel
allocTitle
Acceptable Object Names
neueButton
mCopyLabel
_allocTitle
#arc #auto-synthesized #xcode-4.6.1
** EDIT **
Apparently you can't use mutableCopy either.
The name of the member starting with new is what triggers the warning. Change the name to editedTitle and the warning will go away. I was unable to find documentation confirming this but through testing was able to determine that member variables that begin with 'new' aggravate the compiler.
ARC does not allow to use "New...." in property name. but you can use "newTitle" by changing getter name.
#property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
It doesn't look like what Bavarious was suggesting was what you wanted to do. All you want to do is declare an instance variable NewTitle and then synthesize the property. We used to have to declare the instance variable and property. No more.
Now, I believe the right way of doing this is the following:
.h
#interface ViewController : UIViewController
#property (nonatomic, strong) NSString *newTitle;
.m
#synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
The instance variable for the property newTitle is synthesized. You don't want your instance variable to be the same as your property - too easy to make mistakes.
See Example: Declaring Properties and Synthesizing Accessors
In CoreData if you use "new..." in attribute (compile normally) it will crash randomly with a "bad access" exception.
There is no crash log and the line shown with the "All Exceptions Breakpoint" will not help you at all.
Writing a setter manually with the name same as the property's removed this warning.
NS_RETURNS_NOT_RETAINED is used to solve the naming problem.
#property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
We can find its definition as follows:
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
The 'ns_returns_not_retained' attribute is the complement of 'ns_returns_retained'. Where a function or method may appear to obey the Cocoa conventions and return a retained Cocoa object, this attribute can be used to indicate that the object reference returned should not be considered as an "owning" reference being returned to the caller. The Foundation framework defines a macro NS_RETURNS_NOT_RETAINED that is functionally equivalent to the one shown below.
Besides the issue that you should/can't use "new" in front of you property names, let say one more thing: Try to avoid "new" in front of names in general. "New" is dependent on time. Currently it is new for you, but some time later you maybe want to implement something new again. So using "new" in names is always bad. Try to think this way: In the programming world, "new" is always creating something: a new instance of something.
In your case when you want to assign a different title then the current name your property titleReplacement.
One more thing: Try to name functions and methods with the verb first, like setSomething or getSomething.
But in properties try to name the object first, like heightMinimum, heightMaximum, etc. -> when you use your inspector when you are coding, you always looking for objects. Try it out. ;-)
try this:-
#property (nonatomic,retain) NSString *newTitle;
I really need some clarification — I have a few questions and I'm all mixed up right now.
Here is a simple class interface:
#import <UIKit/UIKit.h>
#interface Car : NSObject{
NSInteger carID;
NSString *carName;
}
#property (nonatomic, assign) NSInteger carID;
#property (nonatomic, copy) NSString * carName;
#end
Why is carID not declared as a pointer?
Why does it use "assign" for carID instead of "copy"?
Why even declare class members as pointers in the first place? (In my main program, my Car object will be used as a pointer.)
NSInteger is simply a typedef for a primitive type (int on 32-bit, long on 64-bit) — it is not an object, and can as such not be retained or copied.
Class members are always pointers; you never pass the "real" objects around; as that would be, at best, unmanageable.
Edit: To expand on the last paragraph: Objective-C class instances always exist on the heap, never on the stack; this is to facilitate things like reference counting and self-managed object life cycle.
This also means that it's very hard to accidentally copy an object; but on the flip side it can be somewhat easier to accidentally dispose of an object you still need. Still, the latter is more readily debugged (as it causes a nice, big crash (at best, anyway)) than the last (which at worst causes a slow leak).
The property for carID is not really correct. For types that are not pointers, the correct definition looks like:
#property (nonatomic) NSInteger carID;
It's always going to be copying a value anyway, but "copy" has a very different meaning in properties - for objects it's going to call [object copy] when that property is used to set a new value.
Or you could drop off the nonatomic, but then the property is more expensive to call (by some small amount). Just leave in the nonatomic unless you have a good reason not to.
Thanks guys!
So in Objective-C , you have int and Pointer Int.
How do you declare these in objective C
-int being a regular int.
-Pointer Int being an object representation of an integer. Since it is an object, it can also point to pointers*. Right?
And Pointer Int pointers can point to pointers of any type If I wanted to. Right?
It will cause a crash if it doesn't point to a Pointer int. But it will compile successfully, Right?
But in what scenarios would I prefer using a regular int to a Pointer Int?
I would like to add some clarification why you would want to use:
#property (nonatomic, copy) NSString * carName;
instead of
#property (nonatomic, retain) NSString * carName;
The copy keyword implies language semantics that you want to have a COPY of the NSString passed into your current object reference. So the pointer does not change (that is why you don't have to release the object ref).
The retain keyword makes it so that you get the pointer which will be retained because the pointer reference changes for this data member (and the current one will be released). Copying a NSString might not be a considerably heavy operation, so copying NSString is used often. You have to be careful what type of property you declare as copy. There might be a considerable amount of effort to produce a copy of types like Dictionaries etc (see shallow, deep copy etc).
Hope that helps!