Document based Obj-C (Mac) app issuing error about nsTextViewObj - objective-c

I'm playing around with Julius Guzy's sample code for creating a document based application that can save text files. I ran his code and it works perfectly and the app runs/save files (All in the latest version of Xcode. Though Guzy's sample code compiles using the 10.6 SDK). I'm trying to learn from it and rewrite the code. I have everything in order to compile the app but for the strangest thing in MyDocument.m. I am unable to run it.
#synthesize nsTextViewObj;
Xcode is giving me this error, which I don't really understand it.
Existing ivar 'nsTextViewObj' for property 'nsTextViewObj' with
assign attribute must be __unsafe_unretained
nsTextViewObj; is suppose to be linked to the "File Owners" in IB. I did that in the first place. It beats me why I'm getting that error. SDK conflicts maybe? How can I fix this?

ARC requires some changes to the code. Xcode provides a tool to automatically convert non-ARC code to ARC: Edit / Refactor / Convert to Objective-C ARC…
The Xcode tool is a good start, still I would recommend you to read Transitioning to ARC Release Notes.
I don't know Julius Guzy's code, but probably you should change it to something like:
#interface ifc_name : NSWindowController {
NSTextView *__unsafe_unretained nsTextViewObject;
}
#property (unsafe_unretained) NSTextView *nsTextViewObject;
As the name implies, unsafe_unretained is not safe: when the object is deallocated, your reference is invalid. If you are deploying only to iOS 5 or higher, and OS-X 10.7 or higher, you can use weak instead. With weak your reference will become zero when the object is deallocated.

Related

Cocoa Static Library – unsafe_unretained Property

I am creating my first static Cocoa Library, and I have noticed a curious thing compared to when I work with Cocoa Applications: When I add an IBOulet to a view in a xib file, the property is made unsafe_unretained by default instead of weak.
Is there any harm done in changing unsafe_unretained to weak?
Thanks,
Michael Knudsen
It happened to me too. i believe that if you'll change it to weak, you won't be able to compile it, because this library (or inner sub libraries) are deployed to an old xcode, which only support unsafe_unretained, but not in weak.
you can change the deployment in the right sidebar.

Convert ARC code to non-ARC

I'm struggling to get an existing ARC-enabled control to run under Xcode 4.2 (OSX Snow Leopard), in a non-ARC-enabled project, and I'm facing various issues :
How should I fix the following issues ?
Use of (strong) in properties
Use of (nonatomic) in properties
Instance methods not found (not having being declared in the interface)
Enable new-style Objective-C
Also, it seems to be complaining about NSScrollerKnobStyle not being defined. Is it a 10.8-to-10.6 SDK-specific issue?
P.S. The control I'm using is ITSidebar
You're going to have to change those strong properties to retain or copy, as appropriate. There's nothing wrong with nonatomic in non-ARC code.
You may have to add #synthesize directives for your properties to get the compiler to add accessor methods. #synthesize is the default in the latest compiler.
There ae a number of other changes to the language, such as object literals. They're all well documented; you just need to apply them in reverse.
I'm not sure about NSScrollerKnobStyle, but if you look it up the documentation will tell you when it was introduced.

#synthesize not showing up for the auto generated properties in Xcode 4.5

I am having Xcode 4.5. I have observed a very strange behavior.In previous versions of Xcode
whenever I control drag the outlets from the nib to .h files, it used to generate getters and setters automatically and #synthesize property clearly shows up in .m file . However if I do the same thing in Xcode 4.5 , #synthesize property doesn't show up. As a result , when I try to run my project created using Xcode 4.5 in Xcode 4.3 or less, it shows the error. When I manually write #synthesize , it works perfectly fine . Any help is greatly appreciated.
You no longer need to #synthesize properties, this is added during compile time to your code by the compiler.
This is a new feature in the latest improvements of the compiler by Apple.
You can #synthesize if you want, it will just take that bit longer and have extra lines of code. By default a property named myProperty, will have automatically an iVar named _myProperty.
Xcode 4.5 contains a newer version of clang, the compiler, that is capable of automatically synthesizing properties. So your observation is expected behavior. If you want to add the #synthesize directives you have to do this manually or use an older version of Xcode.

PhoneGap 2.0.1 Dealloc

I setup a phonegap 2.0.1 project and noticed that it is using ARC. However im wondering if the MainViewController.m which is automatically created for you, that inherits CDVViewController is also run under ARC.
I have added a few properties to the MainViewController like:
#property (nonatomic, readwrite, copy) NSString* errorJS;
And i am wondering If I need to use dealloc to release it, or weather this is already handeld as CDVViewController is run under ARC :S
Can anyone tell me if I still need to release my properties in MainViewController or not?
ARC basically means that you don't have to add release calls because the compiler adds them for you - the binary output from an ARC enabled project (eg libcordova.a) isn't any different from one where the release calls were added manually.
The answer depends on whether or not your project is set to use ARC. I believe the template has ARC turned off by default.
If ARC is enabled, calling release will produce a compiler error. If ARC is disabled, not calling release will usually produce a warning when you run static analysis.

Universal App (iPad+iPhone) targeted to older (iOS < 4) devices - conditionally adopt a protocol?

I'm writing an Universal App that will run natively on both iPad and iPhone. I also need it to be targeted to older devices (those that cannot run 4.0) so 3.1 is a must.
I have already set up the Base SDK to the latest available version (4.2), and the Deployment Target to 3.1. I am making lots of runtime checks in order to call the corresponding methods only on the right device/version.
One of the things I am making use of in the iPad is an UISplitViewController. When assigning the splitViewController delegate, the compiler throws a warning because the class interface isn't explicitly adopting the UISplitViewControllerDelegate protocol and I'm afraid that if I declare it to make it so, the App will crash on older devices where there is no UISplitViewController/UISplitViewControllerDelegate.
What is the best way to supress the compiler warning? Should I declare an 'empty' UISplitViewControllerDelegate? If so, can I make it conditionally at runtime? Or should I just make the corresponding class interface conform to the protocol and not worry about older devices?
Best,
You can suppress the warning with a simple C cast:
foo.delegate = (id<UISplitViewControllerDelegate>)self;
I haven't tried this, but I'm pretty sure you can just go ahead and adopt the protocol unconditionally, even if the class may be used on an older runtime that does not have the protocol. And here's why:
All the information for defining a protocol is contained in the .h file that declares the #protocol. When you adopt a protocol, that protocol declaration is imported at some point in your .h file (presumably by #import <UIKit/UIKit.h>).
When the runtime needs to know something about a protocol, it references a "Protocol Object", which you would normally reference in source code by doing #protocol(MyProtocolName). And the compiler creates this protocol object (at compile time) when such a protocol reference is encountered, according to the section titled Protocol Objects in The Objective-C Programming Language documentation.
So knowing all that, if you adopt a protocol and you write any code that references the protocol object, that protocol object will be created by the compiler. Even if you're running on an older device, the compiler should've created that protocol object for you, so I don't think it'll cause a crash.
Hope that makes sense. If I have some time I can try this out to see if it holds in practice because I have devices running a range of iOS versions from 3.1 to 4.2.
Same problem if you want to use printing and stil have the app runnig before 4.2. Basically it works with this
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40200
// code for iOS 4.2++
#interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPrintInteractionControllerDelegate>{
#else
// code for iOS til 4.1
#interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>{
#endif
But... It looks like the InterfaceBuilder can't handle this. All outlets defines after this conditional definition ar gone in IB.
So any better solution?
Regards
Gerd