Quick fixes to unblock internal test apps#1106
Conversation
ms-jihua
commented
Oct 7, 2016
- Reduces crashes in internal test apps on CT-DW to known issues
| assert(classId != nil); | ||
|
|
||
| pObj->cachedId = [classId alloc]; | ||
| // TODO: #1105 alloc without init is invalid, and not all classes support alloc-init anyway |
There was a problem hiding this comment.
and not all classes support alloc-init anyway [](start = 54, length = 45)
all nsobject deriving ones should?
There was a problem hiding this comment.
nope! [[UIFont alloc] init] crashes on the reference platform
In reply to: 82468031 [](ancestors = 82468031)
There was a problem hiding this comment.
Can't we replace -alloc with NSAllocateObject?
There was a problem hiding this comment.
Seems... undesirable?
https://developer.apple.com/reference/foundation/1587930-nsallocateobject
"This function is deprecated and unavailable for use with ARC."
In reply to: 82673565 [](ancestors = 82673565)
There was a problem hiding this comment.
Well it's just a wrapper for the runtime call to class_createInstance, so deprecated it may be, its behavior is very well defined. We use it elsewhere for this specific case: we want to allocate and zero out a class, but not call + alloc. After a little more digging, we definitely should not call NSAllocateObject, specifically because we break contract in Islandwood by doing some initialization inside + alloc in a bunch of classes in UIKit.
I'm fine with the change as is, it's just a little silly to be putting one-offs (that aren't primitives that need special handling) in the unarchiver code. I'd almost rather see something like a new internal function on NSObject, allocForDecoding, that by default just calls alloc, but can return the default font like you have here for UIFont. Too much to ask for a stop-gap solution, I know. :)
There was a problem hiding this comment.
As commented below, I can remove the one-off, but I'm still concerned about leaving [classId alloc] here:
- alloc without init is considered invalid
- we have a code path here (if classId doesn't support initWithCoder) where we effectively call [[classId alloc] autorelease].
- we appear to have been DEPENDING on this alloc autorelease code path, since if I change this to
if ([classId instancesRespondToSelector:@selector(initWithCoder:)])
pObj->cachedId = [[classId alloc] initWithCoder...]
then things start exploding all over the place with an infinite recursion
we can take care of this separately in #1105, but I wanted to call it out while we're here and make sure you're aware of it
In reply to: 82918436 [](ancestors = 82918436)
|
|
|
@davelamb is added to the review. #Closed |
| assert(classId != nil); | ||
|
|
||
| pObj->cachedId = [classId alloc]; | ||
| // TODO: #1105 alloc without init is invalid, and not all classes support alloc-init anyway |
|
|
||
| pObj->cachedId = [classId alloc]; | ||
| // TODO: #1105 alloc without init is invalid, and not all classes support alloc-init anyway | ||
| // look for a proper fix to this issue, rather than just special-casing for UIFont |
There was a problem hiding this comment.
proper [](start = 22, length = 6)
Not sure if this is an issue, we already have several special cases in this method.
| - (void)_makeConnection { | ||
| // Grab existing collection from the target | ||
| NSMutableArray* collection = [source valueForKey:label]; | ||
| if (source) { |
There was a problem hiding this comment.
This should not be required, you can send messages to nil object. #Pending
There was a problem hiding this comment.
I definitely broke on this the other day but can't repro it anymore. Weird.
In reply to: 82630600 [](ancestors = 82630600)
| // TODO: #1105 alloc without init is invalid, and not all classes support alloc-init anyway | ||
| // look for a proper fix to this issue, rather than just special-casing for UIFont | ||
| if ([classId isEqual:[UIFont class]]) { | ||
| pObj->cachedId = [[UIFont defaultFont] retain]; |
There was a problem hiding this comment.
defaultFont [](start = 38, length = 11)
We should probably create the correct font here (the archive has to have the name?).
There was a problem hiding this comment.
we weren't before, since UIFont doesn't support NSCoding, and I wanted to maintain the existing functionality. I'll wait for dave to comment.
In reply to: 82631100 [](ancestors = 82631100)
There was a problem hiding this comment.
Hm. After a little investigation, it looks like our Xib2Nib and UIFont implementation are a little out of spec. NSFont does indeed implement NSCoding, but it does seem like UIFont doesn't, and so my only conclusion is we're only ever supposed to use UIFontDescriptor to encode/decode on iOS. IE, in UILabel -initWithCoder, _font should be populated with [UIFont fontWithDescriptor:[_coder decodeObjectForKey:@"UIFont[Descriptor]" pointSize:0.0f] and of course we'd have to update Xib2Nib to output the right thing.
Since we're no longer investing in Xib2Nib, I'd say for this is a good enough solution, so long as the new UIFont does still implements initWithCoder.
There was a problem hiding this comment.
Hmm, if it's the case that the UIFont still has to support initWithCoder despite of its doc (was not previously aware of this, and thus current CT-DW UIFont doesn't), then I can just change up UIFont to support alloc and initWithCoder and we won't need the special case here.
In reply to: 82917523 [](ancestors = 82917523)
|
|
Not officially part of the UIFont contract, but needed for our current implementation of UINibUnarchiver
dbba80f to
b41d7c7
Compare