0

I'm using the static code analyser in objective C and I found that using categories to spread a big file in multiple files causes the following problem:

@interface TestClass : UIViewController
@property (nonatomic, assign) UITableView* myTableView;
@end

@implementation TestClass
@end

@interface TestClass (someCategory)
@end

@implementation TestClass (someCategory)
- (void) someMethod
{
    // ...
    CGRect tableViewRect = 
       CGRectMake( sectionRect.origin.x,
                   sectionRect.origin.y + sectionRect.size.height + 1.0,
                   sectionRect.size.width,
                   tableViewHeight);
    myTableView = [[UITableView alloc] initWithFrame:(CGRect) tableViewRect
                             style:(UITableViewStyle) UITableViewStylePlain];
   [self.view addSubView: (UIView*) myTableView];
   [myTableView release];
}
@end

Problem # 1: Compiling TestClass(someCategory) gives me an error "use of undeclared identifier 'theArray'". -> Adding the prefix "self.myTableView" seems to fix the problem.

Problem # 2: Once I have added the "self." prefix before "myTableView", the code analyser complains "incorrect decrement of the reference count of an object that is not owned at this point by the caller" ->I have seen this before in my code: easy to fix by removing the "self." prefix in other, non categorized classes.

So I have a catch 22 situation! - I can't have a class category without prefixing the properties that I use with "self." - The code analyser gives me warnings because it does not seem to understand that my category owns an object that it allocates and frees.

Fixing either of these two problems would work for me (a) finding a way to avoid specifying the ".self" prefix when referencing an attribute from my category implementation (b) finding a way to make the code analyser happy with the fact that I own "self.xxx" where "xxx" is a property of the class that I am categorizing.

Bamaco
  • 592
  • 9
  • 25
  • If you're initializing a table view, adding it to the view, and then releasing it, why are you holding on to the reference in an instance variable? – gregheo Mar 01 '12 at 18:00
  • The scope of the myTableView is that of the viewController. External events from the network may cause my TableViewController to update myTableView, so I need access to the variable. (The release will not take effect until the parent view is released, when I close my viewController) – Bamaco Mar 01 '12 at 18:07

1 Answers1

0

If you need to hold a reference to your table view for the life of the object, you should release it in the dealloc method. Saying [object release] is effectively saying you don't need a reference to the object any more.

If you don't need a reference to the table view, there's no need to use an instance variable/property. Just set up a temporary UITableView * pointer in your method.

Releasing an object from a property getter is usually a bad idea (see this question: Incorrect decrement of the reference count of an object that is not owned at this point by the caller)

Community
  • 1
  • 1
gregheo
  • 4,182
  • 2
  • 23
  • 22
  • I am releasing it in the dealloc method of TestClass – Bamaco Mar 01 '12 at 18:35
  • In that case, you really shouldn't release it in your `someMethod` implementation. The property has the `assign` characteristic so you would be double-releasing. – gregheo Mar 01 '12 at 18:38
  • I am releasing it in the dealloc method of TestClass! Code analyzer complains when I'm allocating from Testclass (someCategory). Removing the [self.myTableView release]; after [self.view addSubView: (UIView*) myTableView]; does not correct the code analyser warning. I've seen something like this elsewhere in my code, in classes not using categories, and removing the "self." prefix from the attribute does quiet the warning. – Bamaco Mar 01 '12 at 18:43
  • What line exactly is the analyzer complaining about? – gregheo Mar 01 '12 at 18:59
  • Code Analyser says that "Incorrect decrement of reference count of an object that is not owned at this point by the caller". This is at the point where I call [self.myTableView release];. Note I have seen 100s of instance of this warning on a "regular" class (as opposed to a category as is the case here). On regular classes, replacing [release self.propertyName] with [release propertyName] quiets the warning. Seems like code analyser is handling "self" as a regular pointer, not recognizing the equivalence of "self.propertyName" and "propertyName" – Bamaco Mar 01 '12 at 19:33
  • Also note that I can't use the [release myTableView] syntax in the context of a category! I have to use [release self.myTableView] otherwise compiler gives me "Use of undeclared identifier" error. – Bamaco Mar 01 '12 at 19:38
  • What I'm saying is if you alloc/init *once* in `someMethod` and release in `dealloc` then you're fine; there's no need to `release` in your `someMethod`. – gregheo Mar 01 '12 at 20:33
  • I understand and agree with what you are saying. The problem is that code analyser gives me a warning unless I release in someMethod – Bamaco Mar 01 '12 at 21:22