0

With XCode 3 compiler, I could manage an array of objects like:

@interface myView:UIView
{
    CALayer *layer[4];
}

@property (nonatomic,retain) CALayer **layer;
@end

@implementation myView
@dynamic layer;

- (CALayer **)layer { return layer; }

// I could then access elements like

- (void) example
{
    self.layer[3] = NULL;
}

@end

With XCode 4 compiler the @property declaration generates an error "Property with retain must be an object type".

I guess best way to fix is to convert to NSArray, but I have 100's lines of code using the c-style array subscript (e.g., self.layer[i]). Is there some other way to fix?

2
  • Okay, found quick answer which is to change default compiler from LLVM to LLVM gcc 4.2. But, would still like to know is there a way to do this with LLVM? Commented Nov 19, 2011 at 18:30
  • 1
    Tracking down the memory leaks and random crashes caused by forgetting to retain/release when you modify the array (and all the extra ones you'll get from not being able to use Automatic Reference Counting) is probably going to cause you more work than fixing this. Commented Nov 19, 2011 at 19:45

3 Answers 3

2

Several problems with this code:

  • It should be MyView, not myView; classes start with capital letters.

  • CALayer ** is not an object type; it is a pointer to an object type, hence the compiler complaint. Simply making it assign will make it compile, but it'll still be wrong.

  • There is likely no reason to use a language array (MyClass foo[4]) to hold this data. Use an NSMutableArray (you can use [NSNull null] as a stand-in for "this slot is not populated".

If you really want to stick with the language array, drop the retain. Just remember that you have to explicitly manage the retain/releases of the objects within the array. The @property won't do that for you.

Also, while it may seem a pain to fix your code to be inline with typical standard patterns, it is only going to be more costly to do so as the code evolves and, someday, you'll likely be in a situation where you really need to do so....

Sign up to request clarification or add additional context in comments.

3 Comments

i would like to know why/how the original code works in gcc.. any thoughts?
The code didn't work in GCC; GCC was just too stupid to catch the error. Making, even, @property work with GCC 4.2 was a nightmare and there were several error cases that simply couldn't be caught without a prohibitive amount of engineering effort.
Ah, that would explain why I have found the behavior of retain/release so baffling, as it was not even working! I guess I improperly extrapolated from some code I found doing the same thing, but without the retain property. Still, I do not see in principle why there is not a way to do what I want. Clearly, I could declare distinct objects, *layer0, *layer1, *layer2, *layer3 and have it work the way I want. So, why not *layer[0], *layer[1], *layer[2], *layer[3]? Actually, I guess that does work fine, just won't synthesize the retain/release, which is okay, now that I understand.
1

Change it to an assign property so you don't try to retain a non-object?

1 Comment

Yes, that is what I am doing. Turns out I have been doing the manual retain/release already anyway, because retain property was not working in gcc, even though the compiler did not complain.
0

You cannot use Objective-C memory management calls (i.e. retain) on a C array. You need to manage your array using standard C or C++ logic. You need to malloc and free memory on your own. If you do not need to retain the array then you can remove the retain property.

1 Comment

As declared, there is no memory management needed of the ivar itself, but of the objects contained within the. The memory for the ivar will be stored inline within the object; no malloc or free needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.