Trying pass the recheck of ARC conversion, but I am not sure how to fix this issue. The method and the property are at odds and I am not sure what to do here:
- (void)getObjects:(id *)objects andKeys:(id *)keys {
return [self.items getObjects:objects andKeys:keys];
}
#interface SoapArray : SoapObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> {
NSMutableArray* items;
}
#property (nonatomic, retain) NSMutableArray* items;
ERRORS WITH:
Sending '__autoreleasing id *' to parameter of type '__unsafe_unretained id *' changes retain/release properties of pointer
You need to update your signature to match the new ARC-compatible getObjects:andKeys:
- (void)getObjects:(id __unsafe_unretained [])objects andKeys:(id __unsafe_unretained [])keys;
The default memory semantic here would be __autoreleasing, but this method returns __unsafe_unretained objects, so you need to as well.
Keep in mind that these are __unsafe_unretained. When you get back your array of id, they have no memory management applied to them. So if self goes away, these objects probably will, too (and they won't zero the pointers like a weak property). That's usually ok and what you want, but keep it in mind.
Related
Icon is set as #property (nonatomic, retain) AHGridIcon *icon;
Usually i just do:
-(void)setIcon:(AHGridIcon *)iconLocal {
icon = iconLocal;
}
But i read a guide to getters setters and properties online which has lead me to believe that instead, this is right:
-(void)setIcon:(AHGridIcon *)iconLocal {
if (iconLocal != self.icon)
{
NSLog(#"local: %#", iconLocal);
NSLog(#"self.icon 1: %#", self.icon);
[iconLocal retain];
[icon release];
icon = iconLocal;
NSLog(#"self.icon 2: %#", self.icon);
}
}
The problem is, the original icon is staying put, it's not being replaced with the new icon. What am i doing wrong? Should i just revert to the usual way i do it?
You should use '#synthesize' unless you really need custom setter behavior.
like I posted in my comment:
the best way is to use #synthesize which will create a getter and a setter to with respect to the properties you wrote in your property (nonatomic, retain) => not threadsafe but fast getter and setter and a retaining (and also releasing) setter. If you dont need sophisticating stuff to do in your setter then you should not override the setter.
.h:
#property (nonatomic, retain) AHGridIcon *icon;
.m:
#implementation Something
#synthesize icon;
...
#end
The code you posted in your setter is nearly the same as the compiler would produce when only using synthesize.
Your usual way is not really nice because in your header is defined (in your property) that the setter is retaining but in your implementation you are overriding that correct setter which doesn't retain. It is nearly the same as the compiler would produce with an (nonatomic, assign) property.
But if you want to override your setter then it should look like the same as you wrote. For me it is working fine.
first retaining the new object
then releasing the old one
then assigning the local pointer to your new object
you can even omit your if but then it is really important that you first retain the new and then release the old objects (like you did - just want to mention that).
For solving your problem with an overriten setter: Your setter looks ok in my eyes. Have you also overriten the getter? If yes then post it here (you use it by calling self.icon in your log-call).
I've done a small test-program
#synthesize str;
- (void)setStr:(NSString *)localStr
{
if(str != localStr)
{
NSLog(#"old : %#", self.str);
NSLog(#"new1: %#", localStr);
[localStr retain];
[str release];
str = localStr;
NSLog(#"new2: %#", self.str);
}
}
and the output is fine:
old : (null)
new1: Hello
new2: Hello
old : Hello
new1: World
new2: World
I am looking for a shorthand way of setting my properties directly to an NSMutableDictionary that is a instance variable. ie:
KVCModle.h:
#interface KVModel : NSObject {
NSMutableDictionary * data;
}
#property(nonatomic,assign)NSString * string1;
#property(nonatomic,assign)NSString * string2;
#end
KVCModel.m
#import "KVModel.h"
#implementation KVModel
-(id)init
{
self = [super init];
if(self)
{
data = [[NSMutableDictionary alloc] init];
}
return self;
}
-(NSString *)string1
{
return [data objectForKey:#"string1"];
}
-(NSString *)string2
{
return [data objectForKey:#"string2"];
}
-(void)setString1:(NSString *)_string1
{
[data setObject:_string1 forKey:#"string1"];
}
-(void)setString2:(NSString *)_string2
{
[data setObject:_string2 forKey:#"string2"];
}
-(void)dealloc
{
[data release];
[super dealloc];
}
#end
I have tried to override setValue:ForKey: and valueForKey:, but those aren't called, they allow you to directly set properties without using the property syntax.
I have made preprocessor macros to make this work in the past, but I am not interested in typing at all, and would like to avoid as much of it as I can in the future. Is there a way to make this work that I am not familiar with?
I have thought about using NSManagedObject, but I am not sure if I can get what I want out of that.
EDIT:
source
If you're trying to access the properties with code like foo = obj.foo and obj.foo = foo, that's why it doesn't work.
Property-access syntax is synonymous with message syntax; the former is exactly the same as foo = [obj foo], and the latter is exactly the same as [obj setFoo:foo]. There is no KVC code to intercept. Properties are at the language level; KVC is at the framework level.
You'll need to intercept the accessor messages instead. Consider implementing the resolveInstanceMethod: class method, in which you “resolve” the selector by adding a method implementation to the class using the Objective-C runtime API. You can add the same implementation(s) for many different selectors.
For your purpose, have a function or method that examines the selector (using NSStringForSelector and regular NSString-examining techniques) and returns two facts: (1) the property name, and (2) whether it's a getter (foo, isFoo) or setter (setFoo:). Then, have two more methods, one a dynamic getter and the other a dynamic setter. When the selector names a getter, add it with your dynamic-getter method; when the selector names a setter, add it with your dynamic-setter method.
So how do the dynamic-getter and -setter methods work? They'll need to know what property to dynamically get and set, but they also need to take no arguments (getter) or one argument (setter, which takes the value), in order to match the original property-access message. You might be wondering how these generic implementations can know what property to get or set. The answer is: It's in the selector! The selector used to send the message is passed to the implementation as the hidden argument _cmd, so examine that selector the same way as before to extract the name of the property you should dynamically get or set. Then, the dynamic getter should send [data objectForKey:keyExtractedFromSelector] and the dynamic setter should send [data setObject:newValue forKey:keyExtractedFromSelector].
Two caveats:
You may still get complaints from the compiler when you use the property-access syntax to access a “property” that you have not declared in the class's #interface. This is normal and intentional; you're really only supposed to use property-access syntax to access known formal properties. What you're doing, while I found it fun to solve, is technically an abuse of the property-access syntax.
This will only work for object values. KVC does the boxing and unboxing for primitive values, such as integers; since KVC is not involved, no free boxing and unboxing. If you have declared formal properties (see 1), you'll need to introspect them using the Objective-C runtime API, and do the boxing and unboxing yourself with your findings.
This piqued my curiosity, so I went ahead and used Peter Hosey's suggestion of overriding +resolveInstanceMethod: to generate the getters and setters. I posted the resulting object (DDDynamicStorageObject) to a github repository:
https://github.com/davedelong/Demos
What you basically want is your own implementation of the NSManagedObject machinery. I have done something similar. Look here: https://gist.github.com/954035 HTH
(Updated the code to remove the dependency on the non-existant NSString+Utilities.h)
(Added missing ReleaseAndZero() macro)
For the love of all that is sacred - do not use an NSDictionary as a place to stuff every conceivable property of a model object. Ivars are easier to debug, and much much clearer to other developers (including your future self).
If you want to use a dictionary, use a dictionary and some statically defined keys - but if you want a model object, use some ivars
I come to the same problem today just like you. So I find your question posted here.
The answers above used the +resolveInstanceMethod: is a little bit hard for me. :)
My understanding is that as long as we setup the property, we would have getter and setter method, so I use the setter method to implement it.
BDLink.h
#property (nonatomic, strong) NSString *type;
#property (nonatomic, strong) NSString *displayName;
#property (nonatomic, strong) NSString *linkURI;
BDLink.m
- (id)initWithLinkInfoDictionary:(NSDictionary *)linkInfoDict {
for (NSString *key in linkInfoDict) {
const char *rawName = [key UTF8String];
NSString *setMethodString = [NSString stringWithFormat:#"set%c%s:", toupper(rawName[0]), (rawName+1)];
SEL setMethod = NSSelectorFromString(setMethodString);
if ([self respondsToSelector:setMethod]) {
[self performSelector:setMethod withObject:linkInfoDict[key]];
}
}
return self;
}
Hope it would be helpful. My first answer, :)
Can anyone explain the difference between setting someObject = someOtherObject; and self.someObject = someOtherObject; if someObject is a class property created with #property (nonatomic, retain) SomeType someObject;
To clarify I have something like:
#interface SomeClass : NSObject {
SomeType* someObject;
}
#property (nonatomic, retain) SomeType* someObject;
#end
I have noticed I get EXC_BAD ACCESS sometimes when I use the property without self and it seems quite random. When I use self my program acts as it should be. I don’t get any compiler errors or warnings when I skip self so I guess it is somehow valid syntax?
self.someObject = someOtherObject makes use of the property. Properties generate setters and getters for you. In your case, you gave the retain attribute to the property, which means that an object set via this property will automatically receive a retain message which increases its retain count by 1. Additionally, the old value of the member variable is sent a release message which decreases its retain count.
Obects are being deallocated, when their retain count reaches 0. You get an EXC_BAD_ACCESS ecxeption if you try to access a deallocated object (e.g. if you try to release it too often).
In your case:
SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
self.someObject = soo; //soo's retain count is now 2
[soo release]; //soo's retain count is 1 again, as self still uses it.
[self doSomethingWithSoo];
However, if you do not use the setter, you must not release soo.
SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
someObject = soo; //soo's retain count is still 1
[soo release]; //soo's retain count is 0, it will be deallocated
[self doSomethingWithSoo]; //will fail with an EXC_BAD_ACCESS exception, as soo does not exist anymore.
Properties are just a convenient way to access the data. So when you are declaring the property #property (nonatomic, retain) SomeType* someObject; this means that during access there would be synthesized 2 methods:
getter:
-(SomeType*) someObject {
return someObject;
}
setter
-(void) setSomeObject:(SomeType*) obj {
[someObject release];
someObject = [obj retain];
}
So the main difference between properties and ivars is that properties dynamically creating the setter/getter methods (and you can override them). But when you're writing someObject = new_val, you're just copying the reference to the memory location. No additional work is done there except one assembly instruction.
There is one more thing to mention: atomic and nonatomic.
With atomic, the synthesized setter/getter will ensure that a whole value is always returned from the getter or set by the setter, regardless of setter activity on any other thread. That is, if thread A is in the middle of the getter while thread B calls the setter, an actual viable value -- an autoreleased object, most likely -- will be returned to the caller in A.
In nonatomic, no such guarantees are made. Thus, nonatomic is considerably faster than atomic.
Edit: so if you have some variable, that is accessed from different threads or/and some additional work has to be done (e.g. retain, raise some flags ...), then your choice is property. But sometimes you have a variable, that is accessed very often and access via property can lead to a big overhead, because processor has to perform much more operations to synthesize and call method.
It's all about memory management.
Your class property someObject have generated accessors with annotation #property / #synthsize in your .h / .m files.
When you are accessing you property with someObject, you directly access the property. When you are accessing self.someObject you are calling your accessor [self someObject] whitch take care of memory management for you.
So when you need to assign a class property it's cleaner to do self.someObject = someOtherObject; because you use the setter and does not have to take care about releasing and retaining. When your setter is generated with #property (nonatomic, retain) so it will take care about retaining for you.
The difference between the two is:
1) when you do not use "self." you are assigning the result directly to the member variable.
2) when you are using "self." you are calling the setter method on that property. It is the same as [self setMyObject:...];
so in case of self.myobject, it keeps its retain, and in other case, (without self), if you are not using alloc, then it will be treated as autoreleased object.
In most cases you will find you want to use "self.", except during the initialization of the object.
By the way, you can also use self.someObject = [someOtherObject retain] to increase retain counter
I'm doing the following:
- (void) accelerometer: (UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration {
if (self.lastAcceleration) {
double i = self.lastAcceleration.x;
It works fine until I actually tilt the phone. Then I get EXC_BAD_ACCESS on the last line. lastAcceleration is a property with a retain. When I look at "x" in the debugger, it has a large negative value. Why would that throw a EXC_BAD_ACCESS exception only on tilt?
-- EDIT (Since this answer applies to responses below) --
I added this and now it works:
- (void)dealloc {
[lastAcceleration release];
Why would that matter? Also, should it be
[self.lastAcceleration release];
I wasn't previously releasing lastAcceleration anywhere. Here is the header declaration:
#interface MyViewController : UIViewController <UIAccelerometerDelegate> {
UIAcceleration *lastAcceleration;
}
#property(nonatomic, retain) UIAcceleration *lastAcceleration;
#end
My hunch is that the accelerometer API has nothing to do with the crash, the code you have shown smells like bad memory management, given that you're mixing ivar and property access I suspect you might be doing the same in other parts you're not showing.
Anyway a couple best practice things:
any object you have a pointer for in your class you should have retained, and conversely when you release it you should also zap the pointer so you don't risk accessing it after it has been deallocated (the exception to this rule are some patterns like the delegate object, where retaining the object would cause a retain cycle, but that's a whole other topic)
ivar setters and getters that are automatically generated via the #synthesized directive will retain and release the object for you for code that simply looks like it's assigning a pointer, so they're pretty handy, but property access (self.something = ...) and ivar access (something = ...) are not equivalent so you have to be careful
One easy way to make sure you don't mix the two up is to do something like this:
#interface MyObject : NSObject
{
SomethingObject *_something;
}
#property (nonatomic, retain) SomethingObject *something;
#end
#implementation MyObject
#synthesize something = _something;
#end
What we're doing here is making the ivar and property names slightly different, so that you are more aware of which one you're using, and the compiler will bark if you use don't use the bare something = ... syntax.
Now the #synthesize'd accessors are something like this:
- (void)setSomething:(SomethingObject *)newSomething
{
[newSomething retain];
[_something release];
_something = newSomething;
}
- (SomethingObject *)something
{
return _something;
}
With all that out of the way, [lastAcceleration release] is a bad thing to do because it isn't also setting the lastAcceleration pointer to nil, you are not guaranteed that it won't be deallocated and if you accidentally use it you are likely to crash.
[self.lastAcceleration release]; is incorrect because accessors take care of all the retain/release stuff for you.
The correct thing to do here is self.lastAcceleration = nil; that, if you look at the accessor code, will release and set the pointer to nil.
What is likely happening is that you are releasing lastAcceleration somewhere without also setting it to nil, and the if (self.lastAcceleration) { check is hitting a released object.
Main reason to have retained properties is to avoid explicit retain/release calls and memory management bugs associated with them. But in dealloc method either way is fine, since object will cease to exist soon.
[self.lastAcceleration release]; - not necessary.
[lastAcceleration release]; self.lastAcceleration = nil;
Both are fine if used in dealloc.
Outside of dealloc use only
self.lastAcceleration = nil;
EXC_BAD_ACCESS is raised when you access released memory. My guess would be that you somewhere released self.lastAcceleration but didn't set it to null.
Are you sure it is related to tilting?
I'm trying to understand how strategies some folks use to distinguish instance vars vs. properties. A common pattern is the following:
#interface MyClass : NSObject {
NSString *_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#end
#implementation MyClass
#synthesize myVar = _myVar;
Now, I thought the entire premise behind this strategy is so that one can easily distinguish the difference between an ivar and property. So, if I want to use the memory management inherited by a synthesized property, I'd use something such as:
myVar = #"Foo";
The other way would be referencing it via self.[ivar/property here].
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Thanks.
Properties are just setters and getters for ivars and should (almost) always be used instead of direct access.
#interface APerson : NSObject {
// NSString *_name; // necessary for legacy runtime
}
#property(readwrite) NSString *name;
#end
#implementation APerson
#synthesize name; // use name = _name for legacy runtime
#end
#synthesize creates in this case those two methods (not 100% accurate):
- (NSString *)name {
return [[_name copy] autorelease];
}
- (void)setName:(NSString *)value {
[value retain];
[_name release];
_name = value;
}
It's easy now to distinguish between ivars and getters/setters. The accessors have got the self. prefix. You shouldn't access the variables directly anyway.
Your sample code doesn't work as it should be:
_myVar = some_other_object; // _myVar is the ivar, not myVar.
self.myVar = some_other_object; // works too, uses the accessors
A synthesized property named prop is actually represented by two methods prop (returning the current value of the property) and setProp: (setting a new value for prop).
The self.prop syntax is syntactic sugar for calling one of these accessors. In your example, you can do any one of the following to set the property myVar:
self.myVar = #"foo"; // handles retain/release as specified by your property declaration
[self setMyVar: #"foo"]; // handle retain/release
_myVar = #"Foo"; // does not release old object and does not retain the new object
To access properties, use self.propname. To access instance variables use just the instance variable's name.
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Because the variable myVar is undeclared.
That statement uses the syntax to access a variable, be it an instance variable or some other kind. As rincewind told you, to access a property, you must use either the property-access syntax (self.myVar = someOtherObject) or an explicit message to the accessor method ([self setMyVar:someOtherObject]).
Otherwise, you're attempting to access a variable, and since you don't have a variable named myVar, you're attempting to access a variable that doesn't exist.
In general, I name my properties the same as my instance variables; this is the default assumption that the #property syntax makes. If you find you're fighting the defaults, you're doing it wrong (or your framework sux, which is not the case for Cocoa/Cocoa-touch in my opinion).
The compiler error you're getting is because property use always has to have an object reference, even inside your own class implementation:
self.stuff = #"foo"; // property setter
[stuff release]; // instance variable
stuff = #"bar"; // instance variable
return self.stuff; // property getter
I know that many Cocoa programmers disagree, but I think it's bad practice to use properties inside your class implementation. I'd rather see something like this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
[stuff release];
stuff = [theStuff copy];
// do something else
}
than this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
self.stuff = theStuff;
// do something else
}
I prefer to do memory management as explicitly as possible. But even if you disagree, using the self.stuff form will clue in any experienced Objective-C programmer that you're calling a property rather than accessing an instance variable. It's a subtle point that's easy for beginners to gloss over, but after you've worked with Objective-C 2.0 for a while, it's pretty clear.
Don,
According to the "rules", you should call Release for every Copy, Alloc, and Retain. So why are you calling Release on stuff? Is this assuming it was created using Alloc, Copy, or Retain?
This brings up another question: Is it harmful to call Release on a reference to an object if it's already been released?
Since Apple reserves the _ prefix for itself, and since I prefer to make it more obvious when I am using the setter and when I am using the ivar, I have adopted the practive of using a prefix of i_ on my ivars, so for example:
#interface MyClass : NSObject {
NSString *i_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#synthesize myVar = i_myVar;
i_myVar = [input retain];
self.myVar = anotherInput;
[i_myVar release]
Since it is quite important to know when you are using the setter and when you are using the ivar, I find the explicitly different name is safer.
In your question, it should be:
self.myVar = #"Foo"; // with setter, equivalent to [self setMyVar:#"Foo"]
and
_myVar = some_other_object; // direct ivar access - no memory management!
Remember that you should not use setters/getters in init/dealloc, so you need to do your direct ivar access (and careful memory management) iin those methods.
what's wrong with simply using
#interface MyClass : NSObject
#property NSString *prop;
#end
nonatomic and retain are not required, retain is the default, and atomic/nonatomic isn\t important unless XCode tells you with a warning.
it is NOT necessary to declare the iVar, one will be created for you named _prop, if you really want to use one (i don't see why to be honest)
#synthesize is NOT required.
when (and you should) using ARC you don't have to bother with retain and release either.
keep it simple !
furthermore, if you have a method like this one
- (void)aMethod:(NSString*)string
{
self.prop = string;
// shows very clearly that we are setting the property of our object
_aName = string;
// what is _aName ? the _ is a convention, not a real visual help
}
i would always use properties, more flexible, easier to read.