Objective C: How to generate warning for instance variables not declared in the class’ interface? - objective-c

I handled several issues recently when working on my company's iOS project using XCode 4.2 and Apple LLVM complier 3.0 / LLVM-GCC.
Below is the code
A.h
#interface A{
int _count;
};
#property(nonatomic,assign) count;
#end
A.mm
#implementation A
#synthesize count = _cont;//note a typo here !!!
//... I use _count in below code
#end
The typo will not generate a compile error or warning, the compiler or run-time (actually I am not sure who did it, to my best guess should be the compiler) will generate a _cont instance ivar for us.
This feature is great for encapsulation. Our header files could be much cleaner. However such a typo is hard to notice. So I am wondering if are there any setting to generate warning for this case? I search Clang's official site without any finding.
Someone would suggest me to not declare the instance in class interface at all and always use self.count. first I don't like this code style, second there are cases your "setCount" method may do something more than just change the instance value,lastly we began our product before this feature is introduced. I don't want to change exist code's style.
Does anyone here encounter the same problem? Are there any good ideas and best practice ?

This is not possible. How should the compiler recognize your typo?
Also you should have recognized that it is not necessary to write your own ivar for your property anymore, as #synthesize count = _count; is already enough to reach you iVar via _count later in the code.

Related

What is an Objective-C "class continuation"?

I can't quite figure out what I have seen referred to as an Objective-C "class continuation". Is this / are these…
Ivar(s) declared in the #implementation (.m) file?
Another name for a class category? (Unlikely, ASFAIK categories cannot have Ivars, period)
Another name for a class extension?
Something else?
That said...
What is the scope, lifetime, and usage case for such a thing?
Is this an ARC-specific "feature"?
Are there specific runtime, or other requirements for their use?
Is this an appropriate place to create an #property, as well? And why would this be a better place for setting ivars or properties than, say, the #interface file / declaration?
Why do people complicate discussions by using such specific terminology - that seems NOT to exist in any official documentation (that I could find)?
In question In Objective-C what is the difference between defining something (say a property) in the header file as opposed to the .m file?
the discussion touches on this issue, but sort of just clouds the issue further - or at least fails to provide a canonical reference / definition of the term… hence this question.
A continuation class is what Apple calls a class extension. I have seen clang call them "continuation class" and gcc uses "class continuation".
Compile this in clang or gcc:
#interface Foo : NSObject
#property int a;
#end
#interface Foo()
#property float a;
#end
... and you will get errors with the funny names.
To answer the rest of your question:
What is the scope, lifetime, and usage case for such a thing?
Extensions are used to declare the private interface for a class. You can also use it to redeclare (refine) public property declarations.
Is this an ARC-specific "feature"?
NO.
Are there specific runtime, or other requirements for their use?
Class Extensions are a compile time concept and do not require a special runtime. Of course they do require a compiler that supports them (both clang and gcc do in current versions).
Is this an appropriate place to create an #property, as well? And why would this be a better place for setting ivars or properties than, say, the #interface file / declaration?
YES. Because you might want to have private properties.
Why do people complicate discussions by using such specific terminology - that seems NOT to exist in any official documentation (that I could find)?
Well, you know... I'd also prefer if the whole world spoke English, but for the time being I'm happy with the fact that I had to learn it in school.

Private Methods in Objective-C, in Xcode 4.3 I no longer need to declare them in my implementation file ?

I have a lot question marks tolling above my head.
What I don't get is before xcode 4.3 I needed to declare forward declarations (for private methods) in my implementation file.
Like in my .m file:
// deleting this with xcode 4.3 the below code still does work
// in previous versions i had to put this because otherwise the compiler can't find methodFirst
#interface DetailViewController ()
- (void)methodFirst;
- (void)methodSecond;
#end
#implementation DetailViewController
- (void) methodSecond
{
// if i delete the forward declaration now adays i dont get a compiler error that he cant find method first
[self methodFirst];
}
- (void) methodFirst
{
}
#end
Now it seems I don't need to do that anymore? Did Apple update the compiler so that it isn't needed anymore to put forward declarations?
I can't find any reference to an official Apple source about this change. I wonder what other people have encountered in their new environment.
As of the LLVM Compiler version shipped with Xcode 4.3, if you try to call a method that the compiler has not previously seen, it will look in the rest of the current #implementation block to see if that method has been declared later. If so, then it uses that, and you don't get a warning. Hence, as of Xcode 4.3, there's much less need to pre-declare your internal methods. Clearly, you still need to declare methods that are publicly exposed to other classes.
This change was noted in the release notes of some of the Xcode 4.3 betas, but apparently didn't make it into the "What's New in Xcode 4.3" final documentation.
Unlike has been suggested in other answers, this is not just an "Undeclared Selector" warning that has been turned off by default. In fact, if you're using ARC, unrecognized selectors are still hard errors. Try calling [self myNonexistentMethod] and you'll see; the compiler still complains.
There aren't any private methods in Objective-C. What you're thinking of is the class continuation, the "nameless" category interface you can declare in your .m file to declare methods that will be in the class implementation, but that aren't in the public interface.
There's never been a requirement to declare methods before they're used. However, it's always been a good idea, and the compiler has a warning flag to indicate when methods that haven't been seen are used. The reason is to do with the operating system's calling convention for functions. Different types, such as structures, floating point numbers, integer numbers, and pointers, can all be handled in different ways when they are the arguments to or return values from functions. Indeed, on different computers and in different operating systems, they are handled in different ways. To know how to handle the arguments and return values for an Objective-C method, the compiler needs to know the signature for that method: how many arguments of what types it takes, and what type it returns.
If it hasn't seen a declaration of the method, then the compiler will need to make a guess. If that guess is incorrect, then it can end up putting the wrong values into the arguments, or interpreting the return value incorrectly, or trying to take something off the stack that doesn't exist.

How to prevent automatic retain/release when calling Obj-C message from C++?

I've got some code like this:
#interface MyTimer : NSObject
- (int)getValue;
#end
#interface TimerHolder : NSObject {
ExternalControl* m_externalControl;
}
#property (retain, nonatomic) MyTimer* timer;
#end
class ExternalControl {
__unsafe_unretained TimerHolder* m_holder;
public:
ExternalControl(TimerHolder* holder) : m_holder(holder);
int getTimer() { return [m_holder.timer getValue] };
};
The method ExternalControl::getTimer() is called very frequently. During profiling, I noticed that during a call to getTimer(), obc-j also calls objc_retain and objc_release (presumably on m_holder or m_holder.timer), which ends up sucking up a lot of time! Removing __unsafe_unretained didn't make a difference.
By construction, I know that whenever ExternalControl::getTimer() is called, m_holder and its timer will stay alive for the duration of the call, so I think the retains/releases are unnecessary.
Is there any way to prevent them from being called?
I'm using XCode 4.2 with iOS 5 SDK, with ARC enabled. Is ARC responsible and removing it would remove the retains/releases? (I didn't want to spend time re-creating a project without ARC just to test this, before checking with you my friends!)
I can only speak from a non-ARC experience as I haven't used it yet (and not planning it being old school).
However, I have several projects using a C++ library and keeping references to it in the obj-C code.
I know for a fact that retain/release isn't called unless explicitly requested.
BTW, I couldn't use Obj-C when linking the C++ library and instead had to use Obj-C++ otherwise the C++ constructor/destructors weren't called as expected. It was just a matter of renaming the .m file into .mm
Hope this help.
If you want to manually handle retain/release for just that class (disable ARC).
set the "-fno-objc-arc" compiler flag in the build phases tab for that source file.
The WWDC 2011 sessions on ARC specifically mention that when compiled for debug, ARC retain/releases are not optimized.
If you haven't, try running your code in Release mode and profiling it. You should see a significant difference.
However, I know ARC doesn't take into account the kind of design assumptions you imply when you say "By construction". But, ARC shouldn't be touching your your "__unsafe_unretained" instance variable... are you sure those retain/release calls are being passed a pointer to that?

dynamic properties in objective c

I found out Objective-C object properties can be marked as #dynamic to let compiler know that implementation will be available at runtime. I'd like to know if there is a way to tell the compiler that all properties on an object are dynamic without explicitly specifying them one-by-one (I don't have a list of properties up front). I know that this would not be a problem if I would just use [object something] but for stylistic purposes I want to use object.something syntax.
I'm fairly sure that it's not possible to do that but I'd like someone to confirm that. Since this is not for production use solution can involve anything you can imagine.
Thanks.
Additional info:
I only care about -something (getter) working so if your solution does not support setters that is fine.
Example:
#interface MagicalClass : NSObject
// property 'something' is not defined!
#end
#implementation MagicalClass
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { ... }
- (void)forwardInvocation:(NSInvocation *)anInvocation { ... }
#end
MagicalClass *obj = [[MagicalClass alloc] init];
[obj something]; // compiler warning
obj.something; // compiler error
This really doesn't work with declared properties. The whole point of them is that you declare upfront what your properties are and how you interact with them. If you don't have any to declare, then you don't have any declared properties.
Unfortunately, it also doesn't work well with plain messages, although it can work better than dot syntax. Objective-C's static type checking will throw a hissy-fit of warnings, and if any of the properties are of non-object types, it might not be able to generate the correct calling code.
This kind of thing is common in languages like Python and Ruby where things don't have to be declared, but it just doesn't mesh well with Objective-C. In Objective-C, accessing arbitrary attributes is generally done with strings (cf. Key-Value Coding and NSAttributedString).
I don't believe this is possible. If you use the id type, you may be able to send undeclared messages, but dot syntax really relies on knowing about your specific accessors.
I haven't tried this, but if you provide a getter and setter, does Xcode still want the #synthesize or #dynamic directive?
So if you property is called something, implement -setSomething: and -something.

Objective-C properties, how do they work?

Assume we have a class Foo with a property bar.
Declared like this in the header:
#interface Foo : NSObject {
int bar;
}
#property (nonatomic, assign) int bar;
#end
In the .m I have #synthesize bar; of course.
Now, my question is, if I remove the int bar; line, the property behaves the same way, so, is that line really necessary? Am I missing some fundamental concept?
Thanks!
The "modern" Objective-C runtime generates ivars automatically if they don't already exist when it encounters#synthesize.
Advantages to skipping them:
Less duplication in your code. And the #property gives the type, name and use (a property!) of the ivar, so you're not losing anything.
Even without explicitly declaring the ivar, you can still access the ivar directly. (One old release of Xcode has a bug that prevents this, but you won't be using that version.)
There are a few caveats:
This is not supported with the "old" runtime, on 32-bit Mac OS X. (It is supported by recent versions of the iOS simulator.)
Xcode may not show autogenerated ivars in the debugger. (I believe this is a bug.)
Because of the debugger issue, at the moment I explicitly add all my ivars and flag them like this:
#interface Foo : NSObject {
#ifndef SYNTHESIZED_IVARS
int ivar;
#endif
}
#property (nonatomic, assign) int bar;
#end
My plan is to remove that block when I've confirmed the debugger is able to show the ivars. (For all I know, this has already happened.)
If there is not a instance variable (ivar) with the same name as the property the modern runtime creates a new ivar of the specified property name to hold the property value when it sees #synthesize.
If your property was not defined nonatomic and you want your code to be threadsafe it may help you to not reference the ivar (whether you declared it or it was synthesized), as that will prevent you from accessing it directly when the property is being changed. To my knowledge there is no way to acquire the same lock that is acquired by #synthesize for an atomic property and therefore you cannot perform safe reads of an atomic property's ivar other than by its synthesized accessor (unless you code an explicit setter and lock something yourself). If you are interested in writing you own accessors I have a blog post on that here.
I believe it is more usual to have an explicit ivar for each property, but this may be because most code is intended to be compatible with the legacy runtime rather than because it is inherently good practice.
Edit: I have corrected paragraph 1 to say that the synthesized ivar has the name of the property; I couldn't see any discussion of its name in Apple's docs so I had assumed it was not user accessible. Thanks to the commenters for pointing this out.
In the latest Objective-C runtime, it turns out that all ivars (in this case, bar) are dynamically added to the class from the #property/#synthesize declaration and do not need a corresponding ivar declaration in the class header. The only caveat to this is that latest Objective-C runtime which supports this feature does not include support for 32 bit applications.
This page from the excellent Cocoa with Love blog explains more.
If you are using the modern Obj-C runtime (e.g. with the LLVM compiler in Xcode 4), the compiler can automatically create the instance variable for you. In that case, you don't need to declare the ivar.
The modern runtime is supported by iOS, the iOS Simulator and 64-bit Mac OS X. You can't build your project for 32-bit OS X with the modern runtime.
I believe it only works that way in 64bit mode. If you try to build for a 32bit target, it will throw an exception.
Scott Stevenson has a good overview of the objective-c 2 changes, and mentions the 64bit runtime changes here