Library in Objective C for OSX - objective-c

I'm creating a library for plotting a particular graph. How do I make it work in both ARC and MRC environment?

Compiled MRC/ARC code can be called from ARC/MRC code - ARC is essentially a compile-time technology which automatically inserts calls to the reference-counting memory management routines. At runtime ARC & MRC code interoperates without issue.
Therefore if you intend to ship your library in compiled form you can write it using either MRC or ARC and it can be used by both ARC & MRC projects.
If you intend to ship your library in source form then you can [was "must", see edit below] write it using MRC. Users can then incorporate your library code directly into MRC projects.
To include it in ARC projects users add the source as usual and then for each source file the file must be marked as using MRC. This is done by selecting the file in the Compiler Sources section of the Build Phases tab of the Project settings and adding the flag -fno-objc-arc. The flag instructs the compiler to compile that particular source file as MRC.
Edit
The above was over strong, in general with ARC being newer than MRC then requirement is to include MRC source in ARC projects, and this is done by flagging the individual MRC files with -fno-objc-arc. However the reverse is equally supported, you can include ARC source in an MRC project by flagging the individual ARC files with -fobjc-arc.
In other words, Xcode has a project-wide setting, "Objective-C Automatic Reference Counting" found in the "Build Settings" pane of the project settings, which sets whether the project is MRC/ARC; and this setting can be reversed for individual source files, in the "Compile Sources" section of the "Build Phases" pane of project settings.
The simplest choice is to distribute your library in binary (compiled) form, as this avoids the user setting any flags.

You can define preprocessor macros for memory management calls that do nothing in ARC, and call the appropriate methods in MRC:
#if __has_feature(objc_arc)
# define ANRelease(obj)
# define ANAutorelease(obj) (obj)
# define ANRetain(obj) (obj)
#else
# define ANRelease(obj) [(obj) release]
# define ANAutorelease(obj) [(obj) autorelease]
# define ANRetain(obj) [(obj) retain]
#endif

You can't.
If you choose to use ARC (advisable) you have a set of restrictions (for instance you cannot manually call any memory management method) that you can bypass only turning it off, which is not really an option because you would end up with memory leaks all over the codebase.
A reasonable way to go is to have two different versions, one with MRC and one with ARC, but it seems like an unnecessary effort.
Your users can import your ARC-based library into a non-ARC project by using the -fobjc-arc compiler flag.

Related

Using autorelease requires disable ARC

Hello I am completely new to Apple development
I used this code in my project
https://github.com/vladinecko/accordion-uitableview/tree/master/AccordionTableView
, project releases the memory itself using autorelease
What made ​​me disable the ARC
Because ARC does not allow the use of autorelease
My question is whether to delete the autorelease from the code
And use ARC or i can not do it and I need to have to release the memory for myself
You could leave the code as-is—you can compile some files using ARC and others not, but that’s going to be messy and hard to maintain.
What I’d recommend doing is running Xcode’s ARC-ifying on the code, to get rid of retain and release and autorelease.
In Xcode 5, look under the “Edit” menu for “Refactor”, and select “Convert to ObjC ARC”.
Apparently AccordionTableView does not use ARC, whereas in your project you are using it.
So you have three options
Switch off ARC only for the separate compilation units, which are from AccordionTableView
Adapt the code snippet from AccordionTableView project with ARC guidelines
Switch your own project to not use ARC
First, being new to Objective-C development you need to learn how memory management works. Google for "Apple memory management" and you should find relevant documents.
Before ARC, people did memory management by hand. With ARC, ARC does it for you. The exact same memory management operations should happen, except that with ARC you have less programmer work, and chances to get it right are better.
You have two choices: Either turn ARC off for individual files. This is done in Xcode / target settings / Build phases / Compile sources by adding -fno-objc-arc to the build settings for individual files where you don't want to use ARC. If you use the same files in different projects, you have to do this in every target.
The other choice is to convert the files to ARC. Let the compiler run, remove offending memory management code, which is mostly retain / release / autorelease. If the code uses CoreFoundation functions, then you really need to understand memory management, just hope it doesn't. Use "Analyze" to let the compiler check very carefully that everything is fine.

'__bridge' casts have no effect when not using ARC

When compiling an older project in Xcode 4.5, there is a warning:
'__bridge' casts have no effect when not using ARC
What's the proper way to get rid of this warning, such that the code works well in both ARC and non-ARC projects?
Any individual source file has to either be compiled with ARC or not compiled with ARC. You should just make up your mind which it is and always use that method for the particular source file. Provided you stick to the memory management naming conventions, you can mix ARC and non ARC source files in the same project.
The reason I say the above, is that if you have code that was written for ARC and you compile it without ARC, there will be memory leaks and premature deallocations all over the place thanks to the fact that all of the retains, releases and autoreleases are missing.
With a few #define's it is quite possible to write source files which compile correctly for more than one of MRC, ARC & GC.
Xcode does not allow you to enable both ARC & GC, knowing that we can write:
#if defined(__OBJC_GC__)
# define USING_GC 1
#else
# define USING_GC 0
#endif
#if __has_feature(objc_arc)
# define USING_ARC 1
#else
# define USING_ARC 0
#endif
#if USING_ARC || USING_GC
# define USING_MRC 0
#else
# define USING_MRC 1
#endif
which will define just one of USING_GC, USING_MRC and USING_ARC as 1 and the other two as 0. You can put that in your projects prefix header (.pch).
You can use these defines directly in your code to include/exclude things like bridge casts; or better to define macros for memory calls, casting, etc. which expand to the appropriate code based on the memory model in use.
HTH
Simply turn on ARC for that file:
-fobjc-arc
(Go to Build Phases > Compile Sources > Compiler Flags)

How to programmatically detect automatic reference counting?

This might be a silly question, but I just wanted to know. I want my code to detect if ARC is enabled, programmatically. How do I do that? Is there is any flag that I could check? Actually the problem is that, I have written an open-source library. I have used release and retain in it. if some one else uses my library files using ARC enabled, I dont want them to get any errors. how do I achieve this? or is there any possible ways I can provide any tools to compile my library before using it?
#if !__has_feature(objc_arc)
//Do manual memory management...
#else
//Usually do nothing...
#endif
This is of course a compile-time check, you cannot check for ARC at runtime.
An alternative would be to set the -fno-objc-arc compiler flag for your files that use manual memory management in a project that otherwise uses ARC.
Whether you want to bother with this at all or just use ARC everywhere depends on how backward-compatible you want/need to be. Code that supports both ARC and MRC can get quite hard to read and maintain.
You don't detect it programmatically, it operates based on translations. That is, it is not like Garbage Collection -- which is process-wide, required all linked libraries to support (and implement it correctly in that mode). You can have some files compiled with ARC, and some without.
However, you can detect it at compilation.
As far as the distribution of your library: I would not bother with a translation based system, where ref count ops are conditionally enabled. I would (personally) just support one model (MRC in your case, until you choose to migrate it to ARC), then expect people to link to the library, or if they compile it in a target they configure, to disable ARC. Conditionally enabling/disabling code based on the presence of a feature is asking for tough bugs, particularly when it's likely to affect 9% of your library's lines of code.
NO, you can't, Xcode would not compile in ARC projects if your source uses retain-release

ARC error when compiling

I'm trying to compile using the LLVM GCC 4.0 compiler, and I get this error in multiple of my .m files: ARC forbids explicit message send of 'release'
I've tried using -fno-objc-arc as a compiler flag but that returns the error: Unrecognized command line option "-fno-objc-arc".
How can I solve this?
Simply remove all calls to -release. You're not allowed to call -release under ARC because the compiler will insert all the necessary retain/release calls for you. Read more about ARC here.
The other way is to use the conversion tool, and Xcode can convert your project to ARC (including removing these calls) for you:
To disable ARC entirely, change your build settings:
However I'd recommend you start using ARC, it will make things a lot easier and actually faster too.
If you happen to be using the ASI (http://allseeing-i.com/ASIHTTPRequest/How-to-use) api, refer to this answer as it needs to be built using -fno-obj-arc flags for specific classes... Files doesn't support the ARC feature, how to deal with and refer to the answer titled 'Disable ARC for that one class'

Under automatic reference counting, why are retain, release, and dealloc not allowed?

When trying to use -retain, -release, and -dealloc while building my application using automatic reference counting in Xcode 4.2, I get an error like the following:
Automatic Reference Counting forbids
explicit message send of 'dealloc'
Why am I seeing this error? Are -retain, -release, and -dealloc no longer allowed under automatic reference counting?
Basically:
When using ARC, it's all or nothing. Either the compiler is managing all of the retains/releases/deallocs for you, or it is doing nothing. You cannot intersperse your own calls to them, because the compiler wants to do it all itself. It can make absurd optimizations by doing this (for example, a method that returned an autoreleased object under Manual Memory Management may now produce an object that never ends up in an autorelease pool). If you were to start sprinkling in your own calls to retain and release, then the compiler would have to work with these and wouldn't be able to perform a lot of the optimizations that it wants (and that you should want).
And as an added bonus, invoking -retainCount is now a compiler error! OH HAPPY DAY!
in response to AliSoftware: we CNA mix ARTC and not-ARC frameworks, and also arc and not-ARC source.
(I did it..)
The basic ideas are:
1) compiler will insert/remove calls as a very-very-good cocoa programmer can do
2) cocoa is ANYWAY C code, so we have separate compilations, so the linker CAN link binaries produced by multiple sources. Think it as we can mix asm and cocoa, or C and pascal...
in main opinion the Appleadvantege over c# / java is here: we are alway allows to mix, and, using a COMPILER technique 8non a runtime..) we can rush performance beyond.
Under automatic reference counting, retain, release, and dealloc are not allowed.
If you have an existing code, you can keep using it as is with the -fno-objc-arc you can selectively disable ARC on any file.
If you want to disable ARC on MULTIPLE files:
Select desired files at Target/Build Phases/Compile Sources in Xcode
PRESS ENTER. (double click selects only one file)
Type -fno-objc-arc
Press Enter or Done
As I have pointed out in my answer on Xcode ARC, you can compile specific source files as non-ARC. Dave DeLong's answer is a bit off. It doesn't include the fact that you can instruct the compiler to compile source as non-ARC in an ARC-enabled project (as explained here).