I've been tasked with cleaning up some Clang errors in a code base. I am very new to iPhone development and Objective C, but have found most of the problems trivial... this one is stumping me though, when I'm sure its something embarrassing.
From a ZAttributedString class:
- (id)initWithAttributedString:(ZAttributedString *)attr {
NSParameterAssert(attr != nil);
if ((self = [super init])) {
_buffer = [attr->_buffer mutableCopy];
_attributes = [[NSMutableArray alloc] initWithArray:attr->_attributes copyItems:YES];
}
return self;
}
The clang warning is "Instance variable used while 'self' is not set to the result of '[super or self] init...]', with the dereferencing of attr's _buffer attribute being highlighted.
If it helps, the warning also seems to mention that the problem is found when calling from this method:
- (id)copyWithZone(NSZone *)zone {
return [(ZAttributedString *)[ZAttributedString allocWithZone:zone] initWithAttributedString:self];
}
Can anyone please explain to me what exactly the defect is here?
TIA!
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc), and freed when the object is deallocated.
The self variable is used to represent the instance of the class which is often used in object-oriented programming. It works as a reference to the object. Python uses the self parameter to refer to instance attributes and methods of the class.
What is instance variable in Java? Instance variables in Java are non-static variables which are defined in a class outside any method, constructor or a block.
An instance variable is a variable which is declared in a class but outside of constructors, methods, or blocks. Instance variables are created when an object is instantiated, and are accessible to all the constructors, methods, or blocks in the class. Access modifiers can be given to the instance variable.
Do not use ->
to access instance variables, especially when the ivar is from some other object.
Do this:
_buffer = [[attr string] mutableCopy];
Same goes for that nasty attr->_attributes
. Apparently, ZAttributedStringexposes
attributes` as a property in the private header.
That compiler warning does seem, at the very most optimistic, entirely misleading and, likely, quite wrong in description. Filing a bug to have that clarified would be useful.
Note that @maddy's claim that using ->
to access the instance variables directly in the attr
string passed as it acts like a copy constructor is incorrect.
The incoming attr
may be a ZAttributedString
instance or an instance of a subclass or, really, an instance of any class that implements the same interface as ZAttributedString
. Thus, you really must go through the accessors to guarantee that you are grabbing the correct state.
Now, as an implementation detail, ZAttributedString
could require that the inbound instance be a non-subclassed instance of ZAttributedString
, but it should use isMemberOfClass:
to assert that requirement (and, please, don't do that).
The only spot where direct ivar access is sometimes used to pull state from another object is in the implementation of copyWithZone:
, but that is exceedingly fragile and oft leads to whacky broken behavior. In fact, copyWithZone:
(outside of the various plist compatible value classes) has been rife with fragility and the source of many many many bugs.
It seems like you are seeing the exact same bug as this: "[Bug 15092] New: static analyzer false positive: reports instance variable used while 'self' is not set to the result of [(super or self)] init". It has a very similar code attached to reproduce the bug.
If you run that code in Xcode 4.6.3 you can verify that it gives the same false warning as you are seeing.
The bug was resolved with the comment:
This is fixed in trunk, or at least mostly fixed -- there are still a few edge cases where the warning will fire, but not your project.
(Dave, for now all of the main analyzer engineers do work at Apple, so there's no real need to file duplicates. The LLVM people who don't work at Apple don't have access to Apple Clang, which ships with Xcode, and this fix didn't make Xcode 4.6. You can also get newer checker builds from http://clang-analyzer.llvm.org)
As you can see the bug is fixed but still present in Xcode 4.6. Hold out for the next version of Xcode and the analyzer warning should be gone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With