2

I have a couple third-party libraries (not using cocoapods) in my iOS project, and when I dug into the files of each, I discovered that 4 of these libraries had their own versions of the UIImage+ImageEffects category. So I was about to merge them into one single file, but that got kind of messy:

For instance, one of the libraries, SCLAlertView, has a custom method inside its version of UIImage+ImageEffects which refers back to one of SCLAlertView's classes to access a variable. So if I import that class into the merged file, It would make the new UIImage+ImageEffects dependent on SCLAlertView. I dont feel comfortable about that, and its not pretty. So I need your guys thoughts on this :

  1. What is the best approach to go about this? Should I just go ahead and merge them or keep them as separate files in their respective libraries?

  2. Does having multiple, slightly different, versions of the same category in a project really matter? does it give rise to any issues/conflicts?

  3. i often see this :

    Class _NSZombie_OS_dispatch_group is implemented in both ?? and ?? ...

    in my console. is this by any chance caused by the above thing?

Thanks in advance.

Note: I didnt give the question a generalized name like "multiple versions of same category in one project" because UIImage+ImageEffects is used by lots of libraries for blur effects and has the most chance of ending up as multiple slightly different versions in your project

ShahiM
  • 3,179
  • 1
  • 33
  • 58
  • I don't think it will create any problems but the warning message has come for me at times when I had duplicate build phases entries for the same file. – Satheesh Jan 01 '16 at 09:32

2 Answers2

2

Answering 2 will drive the answer to 1 (and 3 sounds like a bug in the system, you should file it :) ):

Does having multiple, slightly different, versions of the same category in a project really matter? does it give rise to any issues/conflicts?

As long as all method names are unique, there isn't a problem outside of the issue that categories on system classes are awful for the long term maintainability of a codebase.

If, however, the categories all have methods of the same name -- which they likely do -- then only one of them will be used and which one is indeterminate.

Thus, yes, you'll need to merge them. Or, better yet, eliminate them entirely by refactoring them into a helper class or something (then file a bug against the original codebase and have 'em pull the changes).

bbum
  • 162,346
  • 23
  • 271
  • 359
2

If you build and integrate your 3rd party libs as static libraries, every lib is isolated and uses its own version of the category, and things should work fine. In this case, you should keep the categories internal to the libs and avoid exposing them by means of #include in public headers. EDIT: As pointed out by bbum, category methods are not isolated inside their containing static lib; wrapping the libraries as static libs would not solve the OP's problem.

If you just have one build target and integrate the libs by source, things will work OK as long as the duplicate method implementations don't differ (even though this might result in lots of linker warnings).

Issue will arise if the category implementations differ, because the resulting behavior (i.e. which category method is used at runtime) is undefined (see this post). In this case, I don't know a good solution for the problem; a not good (but working) solution would be to rename (prefix) the methods in each lib's category and use the renamed method in the respective lib. E.g. in lib A, you would rename imageByApplyingLightEffectToImage: to a_imageByApplyingLightEffectToImage: and change all calls to that method inside A accordingly. As I said, I would use this approach as a last resort only.

Community
  • 1
  • 1
dr_barto
  • 5,723
  • 3
  • 26
  • 47
  • 1
    The first paragraph is incorrect; there is no isolation of categories implied by static libraries. If static library A adds the method `-doThis` to UIImage and static library B adds `-doThis` to UIImage, only one will be present at runtime and which one is indeterminate. – bbum Jan 01 '16 at 20:13
  • 1
    Thanks @bbum for the correction, I updated my post accordingly. – dr_barto Jan 02 '16 at 16:28