How can i use Objective-C's Property feature in GNUstep? - objective-c

I'm trying to use Objective-C 2.0 feature Property in GNUstep(using Windows).
But i can't use #property sign and #synthesize.
Although All of my codes are correct,compiler can't compile my property code.
Compiler also can't understand "#" sign.
Can i use Property feature in GNUstep.
If it's can use,Please tell me how can i do that?
Thanks you for your time.

The GNUStep GCC compiler does not support #property (or any of the the other Objective-C 2.0 language changes). However, if you can use Clang, you have access to Objective-C 2.0 features at compilation. As long as you can find an Objective-C 2.0-compatible runtime, you're all set. See http://wiki.gnustep.org/index.php/ObjC2_FAQ#Which_Bits_of_Objective-C_2_Work.3F.

Now you can use Clang 3.3 + libobjc2 + GNUstep to compile all the current Objective-C 2.0 language features. (blocks/ARC/properties...)
But if you're on Windows, I think you may have some trouble to run Clang...

Quick answer is that out-of-the-box, you can't. Version 2.0 of the language specification is specific to Apple's implementation. See here for a summary.

Related

Why does objective-c not have API availability checking?

Swift 2 have API availability checking.
The compiler will give you an error when using an API too new for your
minimum target OS
Why can't the objective-c compiler do the equivalent?
I googled objective c API availability checking and only swift 2 results came out so I assume the compiler for objective c can't do that.
Xcode 9.0 brings the runtime availability checking syntax from Swift to Objective-C:
if (#available(macOS 10.9, *))
{
// call 10.9+ API
}
else
{
// fallback code
}
this comes complete with warnings for calling APIs that are newer than your deployment target (if those calls are not wrapped in checks).
finally ;)
The warning (Swift makes it an error) just hadn't been implemented in the Clang compiler for years, but it's not an inherent Objective-C limitation (although due to its dynamic nature, you won't be able to catch all cases), nor Swift terminology.
The Apple macros (e.g., NS_CLASS_AVAILABLE) and source attributes (__attribute__((visibility(...))), __attribute__((availability(...)))) to annotate headers with availability information have been there for years, and they are widely-used in Apple's SDKs. The macros are defined in Foundation's NSObjCRuntime.h, and the Availability.h/AvailabilityMacros.h system headers, and the compiler can (and does) read them.
In early 2015, the -Wpartial-availability warning has been added to Clang's master branch, but this commit/warning hadn't made its way into Apple's version of Clang until (including) Xcode 7.2. You will get an unknown warning option log when adding the warning flag to a project in Xcode 7.2, but the flag is available in Xcode 7.3. There's currently no predefined setting for it, but you can add the flag to Other Warning Flags under Build Settings.
There are other tools that use LLVM libraries to detect partially available APIs, e.g., Deploymate. For my diploma thesis, I developed a tool that integrates directly into Xcode and is based on a modification to the Clang compiler. The code is still online, but I haven't kept up with the general Clang development so it won't be of much use, except for learning purposes. However, the "official" code (linked above) is much cleaner and better.
Edit: Starting with Xcode 9, availability checking will work for Objective-C (and C), too. Instead of using the above-mentioned warning flag, which does not support raising the deployment target temporarily/locally and therefore causes plenty of false positives, there's -Wunguarded-availability, and if (#available(iOS 11, *)) {...} to check and raise the deployment target for the following block of code. It is off by default, but -Wunguarded-availability-new will be on by default, and starts checking anything beyond iOS/tvOS 11, watchOS 4, and High Sierra. More details on that can be found in the Xcode 9 beta release notes, which currently requires signing in with a developer account.
Objective C does not have availability checking as part of the language, as the same result is available via Objective C preprocessor.
That is the "traditional" way of doing that in C derived languages.
Want to know if compiled in debug mode?
#ifdef DEBUG
// code which will be inserted only if compiled in debug mode
#endif
Want to check at compile time for a minimum version?
Use the Availability.h header in iOS, and similar headers for Mac OS X.
This file reside in the /usr/include directory.
just test __IPHONE_OS_VERSION_MAX_ALLOWED with the preprocessor, e.g.:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil]];
}else{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert)];
}
#else
[[UIApplication sharedApplication] registerUserNotificationSettings: (UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert)];
#endif
As Swift does not have a preprocessor, they had to invent a way of doing these kind of checks within the language itself.
If you want to check availability of a method at runtime, please notice that the appropriate way is by using the method respondsToSelector:, or instancesRespondToSelector: (the latter at class level).
You will normally want to combine both approaches, compile time conditional compilation and runtime check.
Objective C method presence verification, e.g. at class level:
if ([UIImagePickerController instancesRespondToSelector:
#selector (availableCaptureModesForCameraDevice:)]) {
// Method is available for use.
// Your code can check if video capture is available and,
// if it is, offer that option.
} else {
// Method is not available.
// Alternate code to use only still image capture.
}
If you want to test if a C function exists at runtime, it is even simpler: if it exists, the function itself it is not null.
You can't use the same identical approach in both languages.
It does these days. Furthermore, with Xcode 11 (including the current Xcode 11.3.1), you can even get it from the snippets. Press the + button towards the top right of Xcode (as shown in the image below).
Then in the search box, type "API". All 3 versions of the snippet for API Availability Check will appear -- Objective C, C and Swift.
Of course, you will get errors in Objective-C code. But you won't find results in google for Objective-C, if you use a term defined for Swift as you will not find kisuaheli website in google if you search for a german word. ;-)
You will get an error linking Objective-C code against a too old SDK. This is simply because the used method or class or $whatever is not defined in the header for that SDK. Again, of course.
This is typical Swift marketing of Apple: Because of the incapability of Swift they have to extend the language to get something, which is quite easy in Objective-C. Instead of clarifying that this is the result of the poorness of Swift, they tell you that this is a great feature of Swift. It is like cutting your fingers and then saying: "We have the great plaster feature!!!!!!!!" And you have to wait only some days and one comes around on SO with the Q: "Why does Objective-C does not have the great plaster feature???????" The simple answer: It does not cut your fingers.
The problem is not to generate the errors. The problem is to have one source code for all versions, so you can simply change the SDK version and get new code (or errors). You need that for easier maintenance.
In Objective-C you simply can use the answer found here:
Conditionally Hide Code from the Compiler or you can do that at runtime as mentioned in the comments to the Q. (But this is a different solution of the problem by nature, because it a dynamic approach instead of a static one as you have to do in Swift.)
The reason for having a language feature in Swift is that Swift has no preprocessor, so the Objective-C solution would not work in Swift. Therefore conditional code would be impossible in Swift and they had to add the plaster, eh, language feature.

Objective-C header parsing

I need to do parsing of some Objective-C headers.
I've tried using Doxygen and parsing the XML output, but it doesn't fully support Objective C headers without comments (it chokes on macros defined in properties, check Doxygen not properly recognizing properties)
I've also tried using appledoc, but the XML output is not complete enough (for example, there is no information of inheritance for classes) and it has the same problem with macros on properties.
I've also tried parsing the output of the library Objective C metadata (using otool), but noticed that the metadata doesn't keep the types on methods (so you get method:(id)param:(id))
Does anyone know a good tool to do what I want? I'm suspecting clang will help me, but so far the -ast-dump and similar options just tries to generate an AST for a source I don't have (only headers).
You may be able to use libclang. libclang is a programmatic interface designed for implementing tools like syntax highlighting and code completion.
clang -ast-dump works for me. (Note that -ast-dump is not supported by the driver, so you have to do some extra work to pass the flags that the driver usually handles. You can use clang -### ... to see exactly what the driver is doing.)
% clang -cc1 -ast-dump -fblocks -x objective-c /System/Library/Frameworks/Foundation.framework/Headers/Foundation.h
[...]
|-ObjCInterfaceDecl 0x1023727c0 <line:50:1, line:96:2> NSObject
| |-ObjCProtocol 0x102371350 'NSObject'
[...]
I think using clang sounds way too hard. I would just use RegEx.
Instead I would write a simple shell script wrapper around Doxygen that comments out the problematic syntax.
It should be pretty simple to change:
#property(nonatomic, retain) BOOL myProperty NS_AVAILABLE_IOS(3_2);
To:
#property(nonatomic, retain) BOOL myProperty /*NS_AVAILABLE_IOS(3_2)*/;
You could even convert things like NS_DEPRECATED() to an #deprecated comment.

How does the new Apple LLVM 4.0 "default synthesize" feature operate?

I was going through the release notes for Xcode 4.4 and noticed this:
LLVM 4.0 Compiler
Xcode now includes the Apple LLVM Compiler version 4.0, including the following newObjective-C language features:
Default #synthesize: automatically synthesizes an #property when unimplemented
I'm intrigued about this feature. How does it work? I have tried by deleting the #synthesize, it doesn't work.
It does work actually, make sure that in your project and target settings the Compiler is set to LLVM 4.0. Then when you delete the #synthesize line you can access it in two ways:
through the accessor with self.myProperty or through the respective instance variable with _myProperty (yeah the underbars are added automatically).
There are many cases where it simply doesn't work. These are all outlined as exceptions here:
http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html
but the most important one, to me, is called
Readwrite Property With Non-Default Getter and Setter
This means that, unless your properties are just public-facing ivars, you need to include a #synthesize. Or to put it another way, if you're using encapsulation well and filling up those setters and getters, you cannot use this.
Later Note: I'm not sure about the conditions specified here, but I find that there is a autosynthesized ivar for just about every situation I encounter.

__attribute__ ((deprecated)) does not work on objective-c protocol methods?

I need to deprecate a single method in objective-c protocol. On normal class/instance methods I add __attribute__ ((deprecated)); after declaration.
It seems, that it does not work on protocol methods. If I mark them deprecated and use them somewhere the project compiles OK, without expected deprecation warning.
Is it a flaw in Apple LLVM 3.1, or am I doing something wrong?
Although the answers here provide some very good information, they are outdated. Starting with Xcode 5.0 and LLVM 5.0 it looks like deprecation warnings for Objective-C protocol methods are recognized. When implementing the method, Xcode 5 flags it:
Warning: Implementing deprecated method
Here are the steps I used to produce a deprecation warning for the implementation of a deprecated protocol method:
Mark the protocol method as deprecated using __deprecated. From the new SDK 7.0 documentation:
__deprecated causes the compiler to produce a warning when encountering code using the deprecated functionality. __deprecated_msg() does the same, and compilers that support it will print a message along with the deprecation warning. This may require turning on such warning with the -Wdeprecated flag. __deprecated_enum_msg() should be used on enums, and compilers that support it will print the deprecation warning.
#define __deprecated __attribute__((deprecated))
To deprecate your method, do something like this:
- (void)aDeprecatedProtocolMethod __deprecated;
This alone should be enough for Xcode to display a deprecation warning. However, you should follow the next few steps (knowing that Xcode can be very finicky at times) to ensure the warning displays.
Add a documentation comment with a deprecation warning tag. See the code example below to learn how:
/** Describe the method here - what does it do, how does it work, etc. Very brief.
#deprecated This delegate method is deprecated starting in version 2.0, please use otherMethodNameHere:withAnExtraParameter: instead. */
- (void)aDeprecatedProtocolMethod __deprecated;
Clean the project (⌘+⇧+K) and then Build the project (⌘+B) - just because Xcode can be funky sometimes.
I'm not 100% sure when or where this feature was introduced (maybe with SDK 7.0 and 10.9, or Xcode 5.0 / 5.0.1, or with LLVM 5.0) - but it works nonetheless.
Well, I just realised, that even Apple use __attribute__((deprecated)) at the end. And it does not work either. If I use any deprecated delegate method, e.g.
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath
there is no warning.
So it seems like a candidate for radar.
EDIT: filed a radar, Bug ID# 11849771.
Apple deprecated some methods in the UITableViewDelegate protocol, perhaps you'll be able to find the solution using Apple's code as example.
The relevant code of the protocol is as follows:
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath
__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_0);
As you can see, Apple uses a macro. Perhaps this is the way to go?
EDIT: As noted on the following link [1] __attribute__((deprecated)) is a GCC construct so this might not work in LLVM. I guess this is the reason Apple uses macros, so some other (or no) deprecation construct will be called when other compilers are used.
[1] How to deprecate a method in Xcode

Objective-C : Properties question

As far as I understand when you use properties the compiler still converts them to accessor methods during compilation. I got a little irritated when I read you need OSX 10.5 or later to use properties. Why is that so?
If in the compiled application are in fact still accessor methods I see no need for OSX 10.5. Or is there something else going on during run-time?
Because the Objective-C 2.0 runtime was not back ported to 10.4. You need compiler and runtime support to handle all of ObjC 2.0 properly.