Re: Cocoa-dev Digest, Vol 12, Issue 299
Re: Cocoa-dev Digest, Vol 12, Issue 299
- Subject: Re: Cocoa-dev Digest, Vol 12, Issue 299
- From: Jonathan Prescott <email@hidden>
- Date: Fri, 29 May 2015 16:12:46 -0400
How’s this?
#define SUPER_INIT \
do { \
self = [super init]; \
if (self == nil) return self; \
} while(1);
The do … while() construct is an old C/C++ trick used in macro programming to address issues with the pre-processor text insertion process. Makes sure that an entire statement block is presented after the insertion is completed. Most compilers these days optimize the test away. Since you won’t be looking at it much during normal coding, you should not have to puzzle over the seeming nonsense of the code itself as you are using it.
Don’t forget the backslashes.
Jonathan
> On May 29, 2015, at 2:34 PM, email@hidden wrote:
>
> Send Cocoa-dev mailing list submissions to
> email@hidden
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.apple.com/mailman/listinfo/cocoa-dev
> or, via email, send a message with subject or body 'help' to
> email@hidden
>
> You can reach the person managing the list at
> email@hidden
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Cocoa-dev digest..."
>
>
> Today's Topics:
>
> 1. Re: Looking at self = [super init]. (Jean-Daniel Dupas)
> 2. Re: Looking at self = [super init]. (Quincey Morris)
> 3. Re: Looking at self = [super init]. (Simone Tellini)
> 4. Re: Looking at self = [super init]. (Alex Zavatone)
> 5. Re: NSDocumentTitlebarPopoverViewController zombie on
> Yosemite (Matthew LeRoy)
> 6. Re: Looking at self = [super init]. (Alex Zavatone)
> 7. Re: Looking at self = [super init]. (Scott Ribe)
> 8. Re: Looking at self = [super init]. (Alex Zavatone)
> 9. Re: Looking at self = [super init]. (Jens Alfke)
> 10. Re: Looking at self = [super init]. (Scott Ribe)
> 11. Re: Looking at self = [super init]. (Alex Zavatone)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Fri, 29 May 2015 19:40:58 +0200
> From: Jean-Daniel Dupas <email@hidden>
> To: Alex Zavatone <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
>
>> Le 29 mai 2015 à 19:22, Alex Zavatone <email@hidden> a écrit :
>>
>> Was just looking at good old object initialization and came across a stupid idea.
>>
>> For most object initialization, we do this:
>>
>> - (id)init {
>> if (self = [super init]) {
>> // Set up stuff here.
>> // this could get long.
>> }
>> return self;
>> }
>>
>> in some cases, the set up within the parens could get pretty long. In cases like that, I generally set up another method to handle that for organization, but if you're passing objects into into your init method, then you're passing more data again and the code could get less cleaner looking than it could be.
>>
>> So, I thought, "why don't we check if self != [super init] and then immediately return if that is the case?"
>>
>> That would change object initialization to this:
>>
>> - (id)init {
>> if (self != [super init]) {
>> return;
>> }
>>
>> // Set up stuff here.
>> // We don't care if this gets long.
>> // We really don't. This could go on and on.
>>
>> return self;
>> }
>>
>
> And now that a reread the code, it is patently wrong.
>
> if (self = [super init]) is a assignment to self not a comparison.
>
> If you want to do a fast path, you have to do
>
> self = [super init];
> if (!self)
> return nil;
>
>
>
>
>
>
> ------------------------------
>
> Message: 2
> Date: Fri, 29 May 2015 17:42:02 +0000
> From: Quincey Morris <email@hidden>
> To: Jean-Daniel Dupas <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID:
> <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
> On May 29, 2015, at 10:35 , Jean-Daniel Dupas <email@hidden> wrote:
>>
>> You must at least returns nil in the fast path, else the compiler will not be happy.
>
> Shame on you, Jean-Daniel, for not spotting the other error!
>
> On May 29, 2015, at 10:22 , Alex Zavatone <email@hidden> wrote:
>>
>> if (self != [super init]) {
>> return;
>> }
>
> The opposite of ‘if (self = [super init])’ isn’t ‘if (self != [super init])’. The correct code is:
>
> self = [super init];
> if (self == nil)
> return nil;
>
>> I'm not smoking crack here, am I?
>
> We only have your word for it.
>
>> Does this actually seem like a good idea?
>
>
> Of course it’s a good idea (minus the two glaring bugs).
>
>
>
>
>
> ------------------------------
>
> Message: 3
> Date: Fri, 29 May 2015 19:47:55 +0200
> From: Simone Tellini <email@hidden>
> To: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
>
>> Il giorno 29/mag/2015, alle ore 19:38, Alex Zavatone <email@hidden> ha scritto:
>>
>> DOH. Good catch. Sorry, was typing out by hand instead of copying and pasting. I'm actually returning nil in the real class.
>>
>> So, that should be this:
>>
>> - (id)init {
>> if (self != [super init]) {
>> return nil;
>> }
>>
>> // Set up stuff here.
>> // We don't care if this gets long.
>> // We really don't. This could go on and on.
>>
>> return self;
>> }
>
> what if [super init] returned something different than self, yet not nil?
>
> In that case, your code wouldn’t be correct, as a general rule...
>
> --
> Simone Tellini
> http://tellini.info
>
>
>
>
>
>
> ------------------------------
>
> Message: 4
> Date: Fri, 29 May 2015 13:49:32 -0400
> From: Alex Zavatone <email@hidden>
> To: Jean-Daniel Dupas <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=iso-8859-1
>
>
> On May 29, 2015, at 1:40 PM, Jean-Daniel Dupas wrote:
>
>>
>>> Le 29 mai 2015 à 19:22, Alex Zavatone <email@hidden> a écrit :
>>>
>>> Was just looking at good old object initialization and came across a stupid idea.
>>>
>>> For most object initialization, we do this:
>>>
>>> - (id)init {
>>> if (self = [super init]) {
>>> // Set up stuff here.
>>> // this could get long.
>>> }
>>> return self;
>>> }
>>>
>>> in some cases, the set up within the parens could get pretty long. In cases like that, I generally set up another method to handle that for organization, but if you're passing objects into into your init method, then you're passing more data again and the code could get less cleaner looking than it could be.
>>>
>>> So, I thought, "why don't we check if self != [super init] and then immediately return if that is the case?"
>>>
>>> That would change object initialization to this:
>>>
>>> - (id)init {
>>> if (self != [super init]) {
>>> return;
>>> }
>>>
>>> // Set up stuff here.
>>> // We don't care if this gets long.
>>> // We really don't. This could go on and on.
>>>
>>> return self;
>>> }
>>>
>>
>> And now that a reread the code, it is patently wrong.
>>
>> if (self = [super init]) is a assignment to self not a comparison.
>>
>> If you want to do a fast path, you have to do
>>
>> self = [super init];
>> if (!self)
>> return nil;
>>
>
> Thanks much. I knew there was something I was missing there that one of you would see.
>
> Would this handle it properly?
>
> if (!(self = [super init])) {
> return nil;
> }
>
>
> ------------------------------
>
> Message: 5
> Date: Fri, 29 May 2015 17:49:54 +0000
> From: Matthew LeRoy <email@hidden>
> To: "Gary L. Wade" <email@hidden>
> Cc: "email@hidden" <email@hidden>
> Subject: Re: NSDocumentTitlebarPopoverViewController zombie on
> Yosemite
> Message-ID: <D18DEECF.C547%email@hidden>
> Content-Type: text/plain; charset="Windows-1252"
>
> Good to know. Duplicate radar filed, rdar://problem/21145343.
>
> We saw the same issue starting with 10.10.3 and continuing through current 10.10.4 builds. Write up a radar and reference radar://problem/20368338 as a duplicate instance.
> --
> Gary L. Wade (Sent from my iPhone)
> http://www.garywade.com/
>
> On May 28, 2015, at 11:34 AM, Matthew LeRoy <email@hidden<mailto:email@hidden>> wrote:
> Hi,
> Anybody know anything about NSDocumentTitlebarPopoverViewController, and/or why I’m getting application crashes due to a zombie’d instance thereof?
> Document-based app, Deployment Target and SDK both 10.8. Built using Xcode 5.1.1 (5B1008) on Yosemite 10.10.3; running on the same system. Here’s what I do:
> 1. Run my app.
> 2. Open an existing document from disk.
> 3. Click on the document name in the window’s titlebar to open the Document name/tag/location popover.
> 4. Wait a second or two.
> 5. Click elsewhere in my document window to close the popover.
> 6. Crash.
> Sometimes the crash happens immediately after the popover disappears; other times it happens 1-3 seconds later. It doesn’t happen every time, but always within two to three repetitions of steps 3–5. Here’s the stack trace when it crashes:
> frame #0: 0x00007fff84a13d20 CoreFoundation`___forwarding___ + 768
> frame #1: 0x00007fff84a13998 CoreFoundation`__forwarding_prep_0___ + 120
> frame #2: 0x00007fff92603547 ViewBridge`-[NSRemoteViewBase endAllModalSessions:] + 177
> frame #3: 0x00007fff925fbe74 ViewBridge`-[NSRemoteViewBase viewWillMoveToWindow:] + 367
> frame #4: 0x00007fff864b90de AppKit`-[NSView _setWindow:] + 257
> frame #5: 0x00007fff849ea705 CoreFoundation`__53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 133
> frame #6: 0x00007fff849e9e09 CoreFoundation`-[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 313
> frame #7: 0x00007fff86c3d474 AppKit`__21-[NSView _setWindow:]_block_invoke735 + 169
> frame #8: 0x00007fff864b9c54 AppKit`-[NSView _setWindow:] + 3191
> frame #9: 0x00007fff864c73d7 AppKit`-[NSVisualEffectView _setWindow:] + 214
> frame #10: 0x00007fff86722747 AppKit`-[NSPopoverFrame _setWindow:] + 111
> frame #11: 0x00007fff8670961f AppKit`-[NSWindow dealloc] + 1201
> frame #12: 0x00007fff8679c9f5 AppKit`-[_NSPopoverWindow dealloc] + 74
> frame #13: 0x00007fff864b68cc AppKit`-[NSWindow release] + 193
> frame #14: 0x00007fff8497fdb0 CoreFoundation`CFRelease + 304
> frame #15: 0x00007fff849a0bbd CoreFoundation`-[__NSArrayI dealloc] + 125
> frame #16: 0x00007fff9211d89c libobjc.A.dylib`objc_object::sidetable_release(bool) + 236
> frame #17: 0x00007fff92103e8f libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 575
> frame #18: 0x00007fff849a16f2 CoreFoundation`_CFAutoreleasePoolPop + 50
> frame #19: 0x00007fff8c1c1762 Foundation`-[NSAutoreleasePool drain] + 153
> frame #20: 0x00007fff8650ccc1 AppKit`-[NSApplication run] + 800
> frame #21: 0x00007fff86489354 AppKit`NSApplicationMain + 1832
> After enabling Zombie Objects, I get the following in the console:
> 2015-05-28 14:19:58.291 MyApp[23684:2561441] *** -[NSDocumentTitlebarPopoverViewController isKindOfClass:]: message sent to deallocated instance 0x600000146f60
> Google is no help, although it did uncover the following tweet from just a few days ago: https://twitter.com/tonyarnold/status/603424801152086017.
> Anybody run across this before, or have any thoughts on what the problem could be and/or how to debug?
> Thanks!
> Matt
>
>
>
> ------------------------------
>
> Message: 6
> Date: Fri, 29 May 2015 14:02:03 -0400
> From: Alex Zavatone <email@hidden>
> To: Quincey Morris <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=windows-1252
>
>
> On May 29, 2015, at 1:42 PM, Quincey Morris wrote:
>
>> On May 29, 2015, at 10:35 , Jean-Daniel Dupas <email@hidden> wrote:
>>>
>>> You must at least returns nil in the fast path, else the compiler will not be happy.
>>
>> Shame on you, Jean-Daniel, for not spotting the other error!
>>
>> On May 29, 2015, at 10:22 , Alex Zavatone <email@hidden> wrote:
>>>
>>> if (self != [super init]) {
>>> return;
>>> }
>>
>> The opposite of ‘if (self = [super init])’ isn’t ‘if (self != [super init])’. The correct code is:
>>
>> self = [super init];
>> if (self == nil)
>> return nil;
>>
>>> I'm not smoking crack here, am I?
>>
>> We only have your word for it.
>>
>>> Does this actually seem like a good idea?
>>
>>
>> Of course it’s a good idea (minus the two glaring bugs).
>
>
> Heh, yeah, it's been a LOOOONG week. I certainly can't see through the glare too well.
>
> Regarding Daniel's next email, yeah, I kind of really dislike the extra indent for the entire init function. It just seems so wrong.
>
> Glad I asked. I'm certainly not the first person to come across this. Daniel's friend's solution seems good. However, the !self comment shows the same error Simon points out below.
>
> Also, Simon points out another error in my assumption.
>
>> what if [super init] returned something different than self, yet not nil?
>>
>> In that case, your code wouldn’t be correct, as a general rule...
>
> Hmmm. This little comparison does flip the BOOL.
>
> if (!(self == [super init]))
>
> Anyway, thanks for the Friday feedback and observations.
>
> Cheers,
> Alex Zavatone
>
> ------------------------------
>
> Message: 7
> Date: Fri, 29 May 2015 12:16:53 -0600
> From: Scott Ribe <email@hidden>
> To: Alex Zavatone <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
> On May 29, 2015, at 11:49 AM, Alex Zavatone <email@hidden> wrote:
>>
>> Would this handle it properly?
>>
>> if (!(self = [super init])) {
>> return nil;
>> }
>
> Yes.
>
>> if (!(self == [super init]))
>
> No. But not sure whether you were asking about that or not…
>
> --
> Scott Ribe
> email@hidden
> http://www.elevated-dev.com/
> https://www.linkedin.com/in/scottribe/
> (303) 722-0567 voice
>
>
>
>
>
>
>
>
> ------------------------------
>
> Message: 8
> Date: Fri, 29 May 2015 14:17:39 -0400
> From: Alex Zavatone <email@hidden>
> To: Scott Ribe <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=windows-1252
>
>
> On May 29, 2015, at 2:16 PM, Scott Ribe wrote:
>
>> On May 29, 2015, at 11:49 AM, Alex Zavatone <email@hidden> wrote:
>>>
>>> Would this handle it properly?
>>>
>>> if (!(self = [super init])) {
>>> return nil;
>>> }
>>
>> Yes.
>>
>>> if (!(self == [super init]))
>>
>> No. But not sure whether you were asking about that or not…
>
> Typing == by habit. My mistake.
>
>
> ------------------------------
>
> Message: 9
> Date: Fri, 29 May 2015 11:19:13 -0700
> From: Jens Alfke <email@hidden>
> To: Alex Zavatone <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=utf-8
>
>
>> On May 29, 2015, at 11:02 AM, Alex Zavatone <email@hidden> wrote:
>>
>> Regarding Daniel's next email, yeah, I kind of really dislike the extra indent for the entire init function. It just seems so wrong.
>
> That’s sort of a religious issue. Some people think early returns from functions are wrong, because they make the flow of control less structured. (Pascal doesn’t have a ‘return’ statement at all, at least none of the dialects I ever used.) IIRC some functional languages don’t support early-return either.
>
> I tend to prefer early returns, but at the same time I agree that they are sometimes confusing, especially for someone reading a function for the first time. FWIW, the Google style guide says to use early returns for quick-reject tests at the start of a function, which is what we’re talking about here.
>
> On the other hand, the structure of an Obj-C ‘init’ method is such a well-known idiom that I’m reluctant to mess with it. Everyone knows how control flows in a normal init method, so if they se one that doesn’t look like that, it takes a bit longer to figure out what’s going on.
>
> Not to mention that putting assignments in ‘if’ statements is EVIL, even if it does save you a line of code.
>
> —Jens
>
> ------------------------------
>
> Message: 10
> Date: Fri, 29 May 2015 12:22:55 -0600
> From: Scott Ribe <email@hidden>
> To: Alex Zavatone <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=windows-1252
>
> On May 29, 2015, at 12:17 PM, Alex Zavatone <email@hidden> wrote:
>>
>> Typing == by habit. My mistake.
>
> Ah, *NOW* the conversation makes sense ;-)
>
> --
> Scott Ribe
> email@hidden
> http://www.elevated-dev.com/
> https://www.linkedin.com/in/scottribe/
> (303) 722-0567 voice
>
>
>
>
>
>
>
> ------------------------------
>
> Message: 11
> Date: Fri, 29 May 2015 14:34:50 -0400
> From: Alex Zavatone <email@hidden>
> To: Jens Alfke <email@hidden>
> Cc: CocoaDev Cocoa-Dev <email@hidden>
> Subject: Re: Looking at self = [super init].
> Message-ID: <email@hidden>
> Content-Type: text/plain; charset=windows-1252
>
>
> On May 29, 2015, at 2:19 PM, Jens Alfke wrote:
>
>> Not to mention that putting assignments in ‘if’ statements is EVIL, even if it does save you a line of code.
>>
>> —Jens
>
> I tend to agree with you as it makes the code just a little more obtuse. As an example, I went through this entire email thread typing == by habit instead of =.
>
> However, having to go through a few lines just for an init seems like a lot of noise to add to every object initialization. Seems like we could come up with some sort of macro that would replace that and provide an early return.
>
> Having to indent the statements one extra level in an init just seems like an obvious case of "we're doing this wrong - isn't there any way we can do this better?" That and being able to handle leave with an early return make the init method feel nicer to me. I'm just a little too tired at the moment to put a solution together that doesn't fail badly in the non perfect case.
>
> I was thinking about this statement though:
>
> if (! (self = [super init]) ) {
> return nil;
> }
>
> // start initing stuff
> return self;
>
>
> Then there must be a nice way to step back to the original question and see if that could be a macro. I'm sure someone's done that already as well.
>
>
>
>
> ------------------------------
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins (at) lists.apple.com
>
> https://lists.apple.com/mailman/listinfo/cocoa-dev
>
>
> End of Cocoa-dev Digest, Vol 12, Issue 299
> ******************************************
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden