0

This is for a legacy app in my org that was previously running is showing a compile warning and I'm not having any luck debugging it. (I'm not much of an Obj-C dev).

Function is:

static void newDrawTextInRect(UILabel *self, SEL _cmd, CGRect rect)
{
  if (![self.text cxa_doesWrapInvisibleIdentifiers] ||
      !titleSettingsPairs[self.text]){
    origDrawTextInRect(self, @selector(drawTextInRect:), rect);
    return;
  }

  UIImage *img = [titleSettingsPairs[self.text] image];
  CGSize size = img.size;
  CGPoint point = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
  point.x = ceilf(point.x - size.width/2);
  point.y = ceilf(point.y - size.height/2);

  BOOL drawsShadow = ![titleSettingsPairs[self.text] shadowDisabled];
  CGContextRef context;
  if (drawsShadow){
    context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetShadowWithColor(context, CGSizeMake(0, -1), 0, [[UIColor blackColor] colorWithAlphaComponent:1./3.].CGColor);
  }

  [img drawAtPoint:point];
  if (drawsShadow)
    CGContextRestoreGState(context);
}

and the line throwing the error is: UIImage *img = [titleSettingsPairs[self.text] image];

Edit: Adding context around titleSettingsPairs

static NSMutableDictionary *titleSettingsPairs;

&&

+ (void)load
{
  static dispatch_once_t once;
  dispatch_once(&once, ^{
    titleSettingsPairs = [NSMutableDictionary dictionary];
  });
}

&&

+ (void)dealloc
{
  titleSettingsPairs = nil;
}

&&

- (void)cxa_setSettings:(CXAMenuItemSettings *)settings
{
  if (!self.title)
    @throw [NSException exceptionWithName:@"UIMenuItem+CXAImageSupport" reason:@"title can't be nil. Assign your item a title before assigning settings." userInfo:nil];

  if (![self.title cxa_doesWrapInvisibleIdentifiers])
    self.title = [self.title cxa_stringByWrappingInvisibleIdentifiers];

  titleSettingsPairs[self.title] = settings;
}

EDIT: turns out the crash wasn't caused by this issue.

Bryce York
  • 833
  • 1
  • 10
  • 32

2 Answers2

1

try modify

form

UIImage *img = [titleSettingsPairs[self.text] image];

to

UIImage *img = [[UIImage alloc] initWithCIImage:[titleSettingsPairs[self.text] image];
KTang
  • 340
  • 1
  • 17
1

If this expression:

[titleSettingsPairs[self.text] image]

results in a CIImage, one can produce a UIImage from a CIImage as follows...

// change the existing line to assign a CIImage
CIImage *ciImage = [titleSettingsPairs[self.text] image];
// build a UIImage from that 
UIImage *image = [[UIImage alloc] initWithCIImage:ciImage];

But something's not quite right about the story: this wouldn't solve a runtime crash, and the compile time warning would be impossible to see through the collection. Try it and see what what happens, anyway.

Incidentally, consider adding some defensive code to prevent adding nil to a collection, as in:

// so we don't crash if settings is nil
if (settings)
    titleSettingsPairs[self.title] = settings;  // would crash if assigning nil
danh
  • 55,236
  • 10
  • 89
  • 124
  • That resolved the compile warning The image loading from the camera roll is still erroring out. If by any chance you can help, here's a screenshot of what shows up → https://www.dropbox.com/s/tzyna6agtvxgxvf/Screenshot%202017-03-08%2015.04.38.png?dl=0 – Bryce York Mar 08 '17 at 04:03
  • Followed the instructions in the log message that came up and fixed the crash (which was unrelated to the code warning). Thanks for your help. – Bryce York Mar 08 '17 at 04:08
  • 1
    Yes. That screen shot explains the crash. I've had a legacy app crash that way. Starting at OS10 (I think), use of many of the onboard functions photos, contacts, others, requires an info.plist string explaining the app's rationale for them. See here http://stackoverflow.com/a/39519960/294949 – danh Mar 08 '17 at 04:15
  • Used that exact answer to solve the problem. Funny that it was there the whole time, I just didn't read the whole log message. – Bryce York Mar 08 '17 at 04:16