unknown property attribute 'atomic' - ios

When i use FMDB test demo in xcode4.2, everything is good. But when I run the demo in xcode 3.2.6, it gives the error:"unknown property attribute 'atomic'"
__unsafe_unretained id _delegate;
NSUInteger _maximumNumberOfDatabasesToCreate;
}
#property (atomic, retain) NSString *path;
#property (atomic, assign) id delegate;
#property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate;
How can I fix this error ?

As far as I remember "atomic" attribute supported only by clang. When using gcc every property not declared as "nonatomic" is "atomic" by default.

atomic and __unsafe_unretained were introduced with LLVM 3.0. If you are using Xcode 3.2.6, you are using an older version of the compiler that does not support those keywords.
You can safely remove the atomic keyword, since a property is atomic by default; and also remove __unsafe_unretained, since approximately it is equivalent to assign in a property declaration.

You can use Clang's preprocessor macros to determine whether atomic is available in your compiler. If the atomic keyword is not supported, it should be safe to omit it, since atomic is the implicit behavior anyway.
#if __has_feature(objc_atomic)
#property (atomic, retain) NSString *path;
#property (atomic, assign) id delegate;
#property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate;
#else
#property (retain) NSString *path;
#property (assign) id delegate;
#property (assign) NSUInteger maximumNumberOfDatabasesToCreate;
#endif

Related

Adding an object to NSMutableArray - weird behaviour

I am facing a very weird issue. I create an object and I add it to a NSMutableArray but when I try to read it after I insert it, some subclasses of the object change to some weird classes like
PINGIFAnimatedImageManager
Here is the code I use to create the object and insert it to the NSMutableArray:
CustomContentGridRow *row = [[CustomContentGridRow alloc]init];
row.child1 = [dataManager getMapLocation]; // This is the MapLocation object that will change to this weird PINGIFAnimatedImageManager
row.useFullWidth=1;
row.index=0;
[arrCustomChilds addObject:row];
This is the CustomContentGridRow class:
#interface CustomContentGridRow : NSObject
#property (nonatomic, assign) MapLocation *child1;
#property (nonatomic, assign) MapLocation *child2;
#property (nonatomic, assign) int useFullWidth;
#property (nonatomic, assign) int index;
#end
So when I put a breakpoint at this line [arrCustomChilds addObject:hotelRow];, when I read the row object I get the expected results. But when I place a breakpoint after the above code to read the arrCustomChilds the class of child1 changes to some weird classes. Also, sometimes it won't change to another class but it will give nil values.
Any idea why this is happening?
You should change property modifier from "assign" to "strong" for class objects. Otherwise undefined behaviour can happen.
In Xcode -> Product -> Scheme - edit Scheme. Check the settings of RUN mode. If it is Release change to Debug.
This will give you the correct values
Change below properties
#property (nonatomic, strong) MapLocation *child1;
#property (nonatomic, strong) MapLocation *child2;
assign to strong
Your interface should be:
#interface CustomContentGridRow : NSObject
#property (nonatomic, strong) MapLocation *child1;
#property (nonatomic, strong) MapLocation *child2;
#property (nonatomic, assign) int useFullWidth;
#property (nonatomic, assign) int index;
#end
the class objects should be strong not assign

iOS JSONModel property which is correct

if Data is
{ "id": "10", "country": "Germany", "dialCode": 49, "isInEurope": true }
someone using
#interface CountryModel : JSONModel
#property (assign, nonatomic) int id;
#property (strong, nonatomic) NSString* country;
#property (strong, nonatomic) NSString* dialCode;
#property (assign, nonatomic) BOOL isInEurope;
#end
other using
#interface CountryModel : JSONModel
#property (nonatomic) int id;
#property (nonatomic) NSString* country;
#property (nonatomic) NSString* dialCode;
#property (nonatomic) BOOL isInEurope;
#end
Which is better usage?
Both the methods are correct. Declaration of properties depends on your requirement.Properties are used to declare a class’s accessor methods. How can a class access model's data.While declaring property you can then optionally provide set of property attributes that define the storage semantics and other behaviors of the property.When we are defining an object's property as weak/strong we are defining its accessibility to the class.
It depends on how you need to access the data. If you want you object to thread safe,you can define as nonatomic. By defining it as strong/ assign it defines that you own the object.And by defining it as weak you dont own your object. Check this link for more info.
Hope it helps. Happy Coding!!

Is declaring strong actually needed for Objective-C properties?

My understanding so far is that (retain) increases the reference count of a property and is essentially the exact same as (strong). Since all properties are set to retain by default (unless specified otherwise), is adding (strong) needed at all:
#property(nonatomic, strong) NSString *name;
Is the same as:
#property(nonatomic) NSString *name;
Both the above are the same, right?
Since ARC was introduced, "strong", "atomic", and "readwrite" are set by default.
These properties are equivalent:
#property NSArray *name;
#property (strong, atomic, readwrite) NSArray *name;
Source: http://useyourloaf.com/blog/default-property-attributes-with-arc.html
From the documentation:
By default, both Objective-C properties and variables maintain strong
references to their objects.
So both forms are the same.

iOS - Property not found on object of type X - inherited property

I have a CoreData-based app. In Core Data, I have an entity called ZSProduction which creates an NSManagedObject subclass called ZSProductionCD. This is the .h file created.
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface ZSProductionCD : NSManagedObject
#property (nonatomic, retain) NSNumber * appVersion;
#property (nonatomic, retain) id highlightColour;
#property (nonatomic, retain) NSDate * lastUpdated;
#property (nonatomic, retain) NSString * notes;
#property (nonatomic, retain) NSString * owner;
#property (nonatomic, retain) NSString * productionID;
#property (nonatomic, retain) NSString * productionName;
#property (nonatomic, retain) NSNumber * scenesLocked;
#property (nonatomic, retain) NSNumber * shotNumberingStyle;
#property (nonatomic, retain) NSNumber * sortIndex;
#property (nonatomic, retain) NSNumber * status;
#property (nonatomic, retain) NSString * tagline;
#end
I then subclass this with a class called ZSProduction:
#import <Foundation/Foundation.h>
#import "ZSProductionCD.h"
#interface ZSProduction : ZSProductionCD
#end
The reason for subclassing is that I am likely to add a bunch of methods & possibly other properties. This way, if I make changes to the entity, I can write out a new ZSProductionCD class without affecting what I've done with ZSProduction.
Now here's the problem. I'm using ZSProduction in a view controller. But I'm having a problem with just one of the properties.
In this view controller, I declare a property:
#import "ZSProduction.h"
#interface [...]
#property (strong, nonatomic) ZSProduction *item;
#end
And then later, in a method:
self.productionNameField.text = self.item.productionName;
self.shotNumStyleControl.selectedSegmentIndex = [self.item.shotNumberingStyle intValue];
And that's where it goes wrong. XCode complains:
Property 'shotNumberingStyle' not found on object of type 'ZSProduction *'
Note that it doesn't complain about the productionName property, which works fine.
In the same view controller, if I use:
self.item.shotNumberingStyle = 0;
Then I get the same error. But if I use:
[self.item setValue:0 forKey:#"shotNumberingStyle"];
Then it works fine. Yet I can use:
self.item.highlightColour = [UIColor whiteColor];
with no problem at all. What gives?
Any clues would be appreciated.
Well, I sorted the problem, but I thought I'd leave this here in case someone else has something similar.
I realised that the three properties that were being inherited okay, and were accessible, wee ones I'd created in an earlier version of the ZSProduction class - one that didn't use Core Data (I'm currently refactoring to move from archives to CD).
It turned out that there were old ZSProduction.h and ZSProduction.m files on the disk, in the project subdir - but not in XCode. Seems that XCode was looking at these. The old files were in the root dir for the project, while the newer files were in a subdir (called 'Model'). I deleted the old files, restarted XCode & all is now tickety-boo.

Xcode requiring me to redeclare properties as instance variables

I have an object called SCPFAd and it is declared in its header file as follows:
#interface SCPFAd : NSObject
#property (strong, nonatomic) NSArray *imageURLs;
#property (strong, nonatomic) NSString *title;
#property (strong, nonatomic) NSString *price;
#property (strong, nonatomic) NSString *longDescription;
#property (strong, nonatomic) SCPFLocation *location;
#property (strong, nonatomic) SCPFCategory *category;
#property (strong, nonatomic) NSArray *properties;
#property (readonly, strong, nonatomic) NSString *sellerID;
#property (readonly, strong, nonatomic) NSString *timePosted;
- (id)initWithRawData:(NSDictionary *)rawData;
- (BOOL)displaysPrice;
#end
In the implementation file, I have an SCPFAd extension declared this way:
#interface SCPFAd ()
{
NSMutableDictionary *_rawData;
NSMutableArray *_imageURLs;
NSString *_title;
NSString *_price;
NSString *_longDescription;
SCPFLocation *_location;
SCPFCategory *_category;
NSMutableArray *_properties;
}
#property (strong, nonatomic) NSDictionary *rawData;
#property (strong, nonatomic) NSString *sellerID;
#property (strong, nonatomic) NSString *timePosted;
#property (strong, nonatomic) NSString *adID;
#end
I deliberately redeclared the properties rawData, imageURLs, and properties as instance variables because I want external objects to access or assign them as immutable types, but I'll be changing them internally.
What I don't understand is why, when I override the setters, I get a compiler error that says it can't find the variables _title, _price, _longDescription, _location, and _category. The error goes away when I redeclare title, price, longDescription, location, and category as above, but I see it as unnecessary--nothing in the class extension changes their external declarations.
This is how I'm overriding setTitle, for example:
- (void)setTitle:(NSString *)title
{
_title = title;
_rawData[#"name"] = title;
}
- (NSString *)title
{
if (!_title) {
_title = _rawData[#"name"];
}
return _title;
}
If I comment out NSString *_title; in the extension, the compiler says it can't find _title in the first line of the setter, and wherever it occurs in the getter. The getter used to work just fine, though, even without the redeclaration.
If you declare a property and then override both the getter and setter, it won't auto-synthesize the property. But you can just add a line to synthesize it to your implementation:
#synthesize title = _title;
As for having a property be an immutable type, and its backing instance variable be mutable, you're going to have an issue when from outside your class the immutable type is assigned to it, and you treat it as the mutable version, because it won't respond to the methods to mutate it. For example, you assign an NSArray to a variable, then try to treat it as an NSMutableArray, it won't work.
If you implement a getter, the compiler doesn't automatically create an ivar.
This is for a good reason. The property may (and, in my experience, usually is) created on request and returned, so in that case no instance variable is needed to store it and it would add a significant memory overhead to classes with a large number of such properties if every getter had an associated ivar.
One other comment. This:
NSMutableDictionary *_rawData;
// ...
#property (strong, nonatomic) NSDictionary *rawData;
May cause you problems. If rawData is set with an immutable dictionary, it will raise an exception when you attempt to mutate it later. Make sure you copy it on assign using -mutableCopy. (I assume you aren't copying it because it's marked strong, not copy. If you are, it's fine)
When you override the setter and getter (not just the getter), Xcode assumes you want complete control and doesn't create the backing store (the _title). You have to do it yourself with
#synthesize title = _title
If you implement a getter and a setter for a read-write property, or a getter for a read-only property then Clang (Xcode) will not synthesise the backing instance variable - see Apple's Encapuslating Data, note in the section You Can Implement Custom Accessor Methods.
You are implementing both the setter and the getter so you must provide your own instance variable if needed.

Resources