Discussion:
ARC query
(too old to reply)
Jonathan Mitchell
2015-01-07 15:32:39 UTC
Permalink
I use this construct quite a lot without really thinking about it under ARC
I don’t retain a reference to the alert.

Does -beginSheetModalForWindow: completionHandler: cause the receiver to be retained until after the completion handler returns?

NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
alert.messageText = @“Do not touch!";
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
[alert orderOut:self];
}];

Jonathan













_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

Th
Ken Thomases
2015-01-07 18:02:16 UTC
Permalink
Post by Jonathan Mitchell
I use this construct quite a lot without really thinking about it under ARC
I don’t retain a reference to the alert.
Does -beginSheetModalForWindow: completionHandler: cause the receiver to be retained until after the completion handler returns?
NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
[alert orderOut:self];
}];
Well, given your code, it is retained indirectly at least. -beginSheetModalForWindow:completionHandler: has to copy the block, since it survives past its scope. The block has a reference to alert, so, when it is copied, it retains alert until the block copy is fully released and deallocated.

By the way, the documentation for -beginSheetModalForWindow:completionHandler: specifically says that you don't need to call -orderOut: in your completion handler. It will be done after your completion handler exits. Which, by the way, indicates that the alert is retained until then, too.

Short answer: yes, the alert is retained.

Regards,
Ken


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to geg
Sean McBride
2015-01-07 20:55:20 UTC
Permalink
Post by Ken Thomases
Short answer: yes, the alert is retained.
Meaning that one must use the weak/strong dance pattern like this?

NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
alert.messageText = @“Do not touch!";
__weak NSAlert* weakAlert = alert;
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
NSAlert *strongAlert = weakAlert;
[strongAlert orderOut:self];
}];

I miss garbage collection. None of that was necessary. I still haven't got my head around dealing with this under ARC...

Cheers,
--
____________________________________________________________
Sean McBride, B. Eng ***@rogue-research.com
Rogue Research www.rogue-research.com
Mac Software Developer Montréal, Québec, Canada

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.
Mike Abdullah
2015-01-07 21:11:42 UTC
Permalink
Post by Sean McBride
Post by Ken Thomases
Short answer: yes, the alert is retained.
Meaning that one must use the weak/strong dance pattern like this?
NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
__weak NSAlert* weakAlert = alert;
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
NSAlert *strongAlert = weakAlert;
[strongAlert orderOut:self];
}];
I miss garbage collection. None of that was necessary. I still haven't got my head around dealing with this under ARC…
No, no dancing necessary. The completion block is only fired the once. After that it’s discarded, breaking the retain cycle.


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This
Glenn L. Austin
2015-01-09 15:57:25 UTC
Permalink
Post by Mike Abdullah
Post by Sean McBride
Post by Ken Thomases
Short answer: yes, the alert is retained.
Meaning that one must use the weak/strong dance pattern like this?
NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
__weak NSAlert* weakAlert = alert;
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
NSAlert *strongAlert = weakAlert;
[strongAlert orderOut:self];
}];
I miss garbage collection. None of that was necessary. I still haven't got my head around dealing with this under ARC…
No, no dancing necessary. The completion block is only fired the once. After that it’s discarded, breaking the retain cycle.
I think that the key here that may have been missed is that the completion block is *explicitly* released by the dismissal of the alert, which cascades the release to all associated objects.

alert retains block which retains alert. Code exits with releases alert, but the pending block still has a retain on alert. When the block is called, alert is (likely) retained during its execution in order to call the block. Once the block is called alert releases block, which releases *its* retain on alert. The alert finishes its execution and releases itself.

The only need for the strong/weak dance is to implicitly break the object ownership cycle (strong implies ownership of the object, weak explicitly denies ownership of the object). Remember that, and strong/weak become far easier to understand. Of course, all of that assumes that the necessary data for the can be easily re-constructed on demand. And like all generalizations, this doesn't cover all of the use cases, but it may help address some of the confusion about strong/weak and retain cycles.
--
Glenn L. Austin, Computer Wizard and Race Car Driver <><
<http://www.austinsoft.com>


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkiv
Clark S. Cox III
2015-01-07 21:18:32 UTC
Permalink
Post by Sean McBride
Post by Ken Thomases
Short answer: yes, the alert is retained.
Meaning that one must use the weak/strong dance pattern like this?
No. The weak/strong dance would only be needed if NSAlert held on to the completion handler for multiple calls. This is not the case here, the completion handler is called once and is then discarded
Post by Sean McBride
NSAlert *alert = [NSAlert new];
alert.alertStyle = NSWarningAlertStyle;
__weak NSAlert* weakAlert = alert;
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
NSAlert *strongAlert = weakAlert;
[strongAlert orderOut:self];
}];
I miss garbage collection. None of that was necessary. I still haven't got my head around dealing with this under ARC...
--
Clark Smith Cox III
***@gmail.com
Continue reading on narkive:
Loading...