Does the readonly property have an IBOutlet to work and is it preferable?

In the code I inherit, I saw the following:

@property (readonly) IBOutlet UIImageView * bgImage; 

When I would expect to save a memory model, for example:

 @property (readonly, retain) IBOutlet UIImageView * bgImage; 

I am confused why the first property definition works without problems.

In addition, dealloc has a release , as you might expect, for example:

 -(void)dealloc { [_bgImage release]; [super dealloc]; } 

I would appreciate it if anyone could come up with an explanation for this. I spoke with the original developer, and he tried to write more concise code, so he left retain in the memory model (it seemed not necessary).

Interestingly, an IBOutlet is basically processed as an ivar IBOutlet statement, because it is readonly (there is no setting to use, so the assignment memory model does not matter by default).

If an IBOutlet is never expected to change, would using a readonly property without a memory model actually be the preferred way to define properties?

+6
source share
2 answers

The iOS nib loader creates objects in nib and then auto-realizes them. When it establishes connections with outputs, it uses setValue:forKey: which calls the setter method for this key. If the setter is not defined, for example, when the IBOutlet is a readonly property, the object is saved anyway before the assignment. (This is a paragraph of iOS Nib Object Management in the Resource Programming Guide.)

Thus, in fact, regardless of whether the output is declared as retain or assign , the object at the other end belongs to the object with the output. Either it is saved using the setter method, or setValue:forKey: when the setter is not found. Since in the second case there is no other possible owner, you can consider the object to exit as the owner. Therefore, an object in nib must be released in dealloc .

I agree with you that this memory condition should be an explicit way to change property attributes to enable retain . * Regardless of whether it has readonly meaning (see below). Conceptually, yes, the object is read-only, so regardless of whether you should explicitly indicate it, it depends on whether you consider it to be properly documented by the fact that it is an IBOutlet .

UPDATE: Paul.s comment below prompted me to do a quick test. I created a subclass of UIView that registers the calls to alloc , retain , release and autorelease , sticks an instance of it in nib, and passes the IBOutlet application delegate through the property.

By counting the activity of manually counting links, the instance (readwrite, assign) counter of 0 when the property was (readwrite, assign) . This was pure +1 when the property was declared in the recommended way, (readwrite, retain) , and also when it was (readonly, assign) . All this to a large extent, as expected, when it (readwrite, assign) , the assigning setter is used for the connection, and saving is not performed. When it is readonly , the connection mechanism returns to save it.

Most interestingly, when I tried to minimize the application by changing the background color of this view with a declared declaration (readwrite, assign) (i.e. when it was supposedly released), I saw one last call to retain popup.

I think it boils down to the following: follow Apple's recommendations - they know what’s going on behind the scenes and (prohibiting errors) will not direct you to the wrong ones.

(Another thing that needs to be removed is that, as always, worrying about absolute reference counts will not be terribly useful - the count has reached 6 at one point, for two dozen calls to retain and release - you just need to worry about save and release that you invoke directly.)


* Of course, this changes with ARC. The information that I rephrased is in the Deprecated Templates section of the chapter. In ARC, it is recommended that IBOutlets be weak if they are not at the top level, in which case they should be strong . Doing this means that you rely on a view hierarchy (views that retain their subviews) to support themselves.

+7
source

I reported an error with Apple that if you create IBOutlet instance variables instead of properties, then Xcode will still automatically create the release in dealloc, etc. Xcode for iOS apps always creates releases for IBOutlet, whether it’s correct or not.

Personnel I do not like the IBOutlet property, as it means that you declare them as readwrite, which means they are documented as readwrite, but most of the time (almost always) the IBOutlet should conceptually be in read mode only. Obviously, they must be read in order to install them initially.

+2
source

Source: https://habr.com/ru/post/900568/


All Articles