Skip to content

Instantly share code, notes, and snippets.

@emcmanus
Last active December 12, 2015 01:59
Show Gist options
  • Select an option

  • Save emcmanus/4695605 to your computer and use it in GitHub Desktop.

Select an option

Save emcmanus/4695605 to your computer and use it in GitHub Desktop.

Revisions

  1. emcmanus revised this gist Feb 2, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion PFObject+YSComparison.m
    Original file line number Diff line number Diff line change
    @@ -119,7 +119,7 @@ static bool compareBySelectors(SEL selectors[], NSObject* object1, NSObject* obj
    #pragma clang diagnostic pop

    BOOL equal;
    if ([object1 respondsToSelector:@selector(ys_isEqual:)] && [object2 respondsToSelector:@selector(ys_isEqual:)])
    if ([value1 respondsToSelector:@selector(ys_isEqual:)] && [value2 respondsToSelector:@selector(ys_isEqual:)])
    {
    equal = ((value1 == value2) || [value1 ys_isEqual:value2]);
    }
  2. emcmanus revised this gist Feb 2, 2013. 2 changed files with 19 additions and 11 deletions.
    8 changes: 4 additions & 4 deletions PFObject+YSComparison.h
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    @@ -29,13 +29,13 @@

    @interface PFObject (YSComparison)
    - (NSDictionary*)ys_dictionaryRepresentation;
    - (BOOL)isEqual:(id)object;
    - (BOOL)ys_isEqual:(id)object;
    @end

    @interface PFFile (YSComparison)
    - (BOOL)isEqual:(id)object;
    - (BOOL)ys_isEqual:(id)object;
    @end

    @interface PFRelation (YSComparison)
    - (BOOL)isEqual:(id)object;
    - (BOOL)ys_isEqual:(id)object;
    @end
    22 changes: 15 additions & 7 deletions PFObject+YSComparison.m
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    @@ -32,7 +32,7 @@
    #pragma mark - PFFile

    @implementation PFFile (YSComparison)
    - (BOOL)isEqual:(id)object
    - (BOOL)ys_isEqual:(id)object
    {
    if ([self isKindOfClass:[object class]])
    {
    @@ -55,7 +55,7 @@ - (BOOL)isEqual:(id)object
    #pragma mark - PFRelation

    @implementation PFRelation (YSComparison)
    - (BOOL)isEqual:(id)object
    - (BOOL)ys_isEqual:(id)object
    {
    if ([object isKindOfClass:[self class]])
    {
    @@ -82,7 +82,7 @@ - (NSDictionary*)ys_dictionaryRepresentation
    return [NSDictionary dictionaryWithObjects:values forKeys:keys];
    }

    - (BOOL)isEqual:(id)object
    - (BOOL)ys_isEqual:(id)object
    {
    if ([object isKindOfClass:[self class]])
    {
    @@ -117,9 +117,17 @@ static bool compareBySelectors(SEL selectors[], NSObject* object1, NSObject* obj
    id value1 = [object1 performSelector:selector];
    id value2 = [object2 performSelector:selector];
    #pragma clang diagnostic pop

    // Correctly handle nil values
    BOOL equal = (value1 == value2) || [value1 isEqual:value2];

    BOOL equal;
    if ([object1 respondsToSelector:@selector(ys_isEqual:)] && [object2 respondsToSelector:@selector(ys_isEqual:)])
    {
    equal = ((value1 == value2) || [value1 ys_isEqual:value2]);
    }
    else
    {
    equal = ((value1 == value2) || [value1 isEqual:value2]);
    }

    if (!equal)
    {
    return NO;
  3. emcmanus created this gist Feb 2, 2013.
    41 changes: 41 additions & 0 deletions PFObject+YSComparison.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    //
    // PFObject+YSComparison.h
    //
    // Created by Ed McManus for Yardsale Inc. on 2/1/13
    // Learn more at https://getyardsale.com
    //
    // Requires BlocksKit https://github.com/pandamonia/BlocksKit
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    // THE SOFTWARE.
    //

    #import <Parse/Parse.h>

    @interface PFObject (YSComparison)
    - (NSDictionary*)ys_dictionaryRepresentation;
    - (BOOL)isEqual:(id)object;
    @end

    @interface PFFile (YSComparison)
    - (BOOL)isEqual:(id)object;
    @end

    @interface PFRelation (YSComparison)
    - (BOOL)isEqual:(id)object;
    @end
    129 changes: 129 additions & 0 deletions PFObject+YSComparison.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,129 @@
    //
    // PFObject+YSComparison.m
    //
    // Created by Ed McManus for Yardsale Inc. on 2/1/13
    // Learn more at https://getyardsale.com
    //
    // Requires BlocksKit https://github.com/pandamonia/BlocksKit
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    // THE SOFTWARE.
    //

    #import "PFObject+YSComparison.h"

    static bool compareBySelectors(SEL selectors[], NSObject* object1, NSObject* object2);

    #pragma mark - PFFile

    @implementation PFFile (YSComparison)
    - (BOOL)isEqual:(id)object
    {
    if ([self isKindOfClass:[object class]])
    {
    // Skip getData check if it requires a request
    if (![self isDataAvailable] || ![object isDataAvailable])
    {
    SEL selectors[] = { @selector(url), @selector(name), @selector(isDataAvailable), };
    return compareBySelectors( selectors, self, object );
    }
    else
    {
    SEL selectors[] = { @selector(url), @selector(name), @selector(isDataAvailable), @selector(getData), };
    return compareBySelectors( selectors, self, object );
    }
    }
    return NO;
    }
    @end

    #pragma mark - PFRelation

    @implementation PFRelation (YSComparison)
    - (BOOL)isEqual:(id)object
    {
    if ([object isKindOfClass:[self class]])
    {
    SEL selectors[] = {
    @selector(parent),
    @selector(key),
    @selector(targetClass),
    };
    return compareBySelectors(selectors, self, object);
    }
    return NO;
    }
    @end

    #pragma mark - PFObject

    @implementation PFObject (YSComparison)
    - (NSDictionary*)ys_dictionaryRepresentation
    {
    NSArray * keys = [self allKeys];
    NSArray * values = [keys map:^id(NSString *key) {
    return self[key];
    }];
    return [NSDictionary dictionaryWithObjects:values forKeys:keys];
    }

    - (BOOL)isEqual:(id)object
    {
    if ([object isKindOfClass:[self class]])
    {
    SEL selectors[] = {
    @selector(objectId),
    @selector(createdAt),
    @selector(updatedAt),
    @selector(className),
    @selector(ys_dictionaryRepresentation),
    };
    return compareBySelectors(selectors, self, object);
    }
    return NO;
    }
    @end

    #pragma mark -

    /*
    * Compare two objects using a C-style array of selectors.
    */
    static bool compareBySelectors(SEL selectors[], NSObject* object1, NSObject* object2)
    {
    int selectorTypeSize = sizeof(SEL);
    int selectorArraySize = sizeof(*selectors);
    int selectorCount = selectorArraySize / selectorTypeSize;
    for (int i=0; i<selectorCount; i++)
    {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    SEL selector = selectors[i];
    id value1 = [object1 performSelector:selector];
    id value2 = [object2 performSelector:selector];
    #pragma clang diagnostic pop

    // Correctly handle nil values
    BOOL equal = (value1 == value2) || [value1 isEqual:value2];
    if (!equal)
    {
    return NO;
    }
    }
    return YES;
    }