Code Monkey home page Code Monkey logo

libextobjc's Introduction

The Extended Objective-C library extends the dynamism of the Objective-C programming language to support additional patterns present in other programming languages (including those that are not necessarily object-oriented).

libextobjc is meant to be very modular – most of its classes and modules can be used with no more than one or two dependencies.

Features

libextobjc currently includes the following features:

  • Safe categories, using EXTSafeCategory, for adding methods to a class without overwriting anything already there (identifying conflicts for you).
  • Concrete protocols, using EXTConcreteProtocol, for providing default implementations of the methods in a protocol.
  • Simpler and safer key paths, using EXTKeyPathCoding, which automatically checks key paths at compile-time.
  • Compile-time checking of selectors to ensure that an object declares a given selector, using EXTSelectorChecking.
  • Easier use of weak variables in blocks, using @weakify, @unsafeify, and @strongify from the EXTScope module.
  • Scope-based resource cleanup, using @onExit in the EXTScope module, for automatically cleaning up manually-allocated memory, file handles, locks, etc., at the end of a scope.
  • Algebraic data types generated completely at compile-time, defined using EXTADT.
  • Synthesized properties for categories, using EXTSynthesize.
  • Block-based coroutines, using EXTCoroutine.
  • EXTNil, which is like NSNull, but behaves much more closely to actual nil (i.e., doesn't crash when sent unrecognized messages).
  • Lots of extensions and additional functionality built on top of <objc/runtime.h>, including extremely customizable method injection, reflection upon object properties, and various functions to extend class hierarchy checks and method lookups.

The experimental branch contains additional features that may be interesting, but are not considered stable or safe for production use. Check out the headers for more information.

Running tests

To execute libextobjc's tests, first run git submodule update --init --recursive to bring in the xcconfigs submodule, then open the project file and choose the desired test target.

Adding to your project

If you want to add libextobjc as a dependency to an application, add the repository as a submodule, then include the source files you care about in your Xcode project.

If you want to add libextobjc as a dependency to a framework or library, prefer subtree merging, which will allow you to rename symbols to avoid conflicts, and make any tweaks you need to for your library.

To create a libextobjc subtree:

$ git remote add libextobjc https://github.com/jspahrsummers/libextobjc.git
$ git fetch libextobjc
$ git read-tree --prefix=External/ -u libextobjc/master
$ git reset

Rename any symbols or change whatever you want, git add the specific files that you want in your library, and then add them to your Xcode project.

To bring in upstream changes later:

$ git fetch -p libextobjc
$ git merge -Xsubtree=External/ libextobjc/master
$ git reset

Then, again, just add the changes you want.

License

Released under the MIT License. See the LICENSE file for more information.

Requirements

libextobjc must be built with ARC enabled, and many of its macros require ARC in the calling files as well. MRR usage is not supported.

libextobjc's People

Contributors

ahti avatar antondomashnev avatar bigboybad avatar claybridges avatar cuitche avatar diederich avatar fabb avatar flexih avatar grgcombs avatar ikashkuta avatar javisoto avatar jonsterling avatar joshaber avatar joshvera avatar jspahrsummers avatar juliengrimault avatar k-be avatar k06a avatar kolyuchiy avatar ole avatar reiz avatar shepting avatar sibljon avatar timmehmainframe avatar tonyarnold avatar wanganjun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libextobjc's Issues

@concreteprotocol breaks Xcode code-folding.

Not sure where to start with this one... I have no idea how Xcode manages it's cold folding... I will turn on Xcode-Explorer and see if I garner any more insight into it...

I have only noticed this for @concreteprotocol, but may be true of other "added features", as well, I'd imagine...

Compiler error in EXTSynthesize

Hi, I just tried using EXTSynthesize.h and ran into a compiler error, basically on the line that says 'dynamic' in the file. Changing this to @dynamic fixes this error...Any ideas why this might be the case? Seems like too big on an issue to be overlooked, so I just assume I must be doing something funky..

CocoaPod packaging?

Hello,

Very cool project.

Any plans on adding CocoaPod packaging? I made a naive attempt attempt but immediately realised I was way over my head with that.

[Question] Is it possible to do some kind of block argument overloading? (oslt)

Hey Justin! I don't know if this is the right place, but I really would like to ask you about one tricky feature I'm struggling with :)

Is it possible to somehow have a block which would accept an argument of different types without complaining? The argument could be id, but might as well be double or even struct (e.g., CGPoint).

A solution I'm currently using is a macro-based one. I use a macro to wrap scalar/struct arguments in NSValue, using their encoded types, and then retrieve them back. However, this has a drawback of littering global namespace with defines, which may be undesired.

One thing I noticed is that you may do like this:

void (^block)() = ^{
    // do something
};

/**
 *  no syntax errors here 
 *  (because block invocation is actually done via a function 
 *  accepting variable number of parameters, right?)
 */
block(1);
block([NSObject new]);

Perhaps there's a way to retrieve these passed arguments inside the block? We could assume that we actually know which type we are currently expecting.

Maybe there's another clever approach I'm missing? I know you are an expert on all kinds of crazy things, so perhaps you could give me a clue :) Thanks a lot!

Add callable functionality for blocks

The idea is to add a method or function which can determine the 'are you callable/a block' status of a given object. If the object is a block and can be called, return YES, otherwise NO.

"Around" style aspect causes crash

Steps to reproduce:

Create a header

#import <Foundation/Foundation.h>
#import "EXTAspect.h"

@class TyphoonDefinition; //For the purpose of this issue, this just has 'key' property

@aspect(WrapMethod);

@interface ClassWithAspect : NSObject<WrapMethod>

- (TyphoonDefinition*)componentA;

- (TyphoonDefinition*)componentB;

@end

Create an Impl

#import "ClassWithAspect.h"
#import "TyphoonDefinition.h"
#import "Knight.h"
#import "TyphoonInitializer.h"

@aspectimplementation(WrapMethod)

- (TyphoonDefinition*)advise:(TyphoonDefinition*  (^)(void))body
{
    NSLog(@"HERE WE GO!!!!!!!!!!!!!!!!!!");
    TyphoonDefinition* def = body();
    def.key = @"foobar";
    NSLog(@"$$$$$$$$$$$$$ Here's the def: %@", def);
    return def;
}
@end

@implementation ClassWithAspect

- (TyphoonDefinition*)componentA
{
    return [TyphoonDefinition withClass:[Knight class] initialization:^(TyphoonInitializer* initializer)
    {
        initializer.selector = @selector(initWithQuest:);
    }];
}

- (TyphoonDefinition*)componentB
{
    return [TyphoonDefinition withClass:[Knight class] initialization:^(TyphoonInitializer* initializer)
    {
        initializer.selector = @selector(initWithQuest:);
    }];
}


@end

Create a Test Case

@interface ClassWithAspectTests : SenTestCase

@end

@implementation ClassWithAspectTests


- (void) test_wrap_method
{
    ClassWithAspect* anInstance = [[ClassWithAspect alloc] init];
    TyphoonDefinition* aDefinition = [anInstance componentA];

    NSLog(@"Definition: %@", aDefinition);
}

@end

Expected test not to crash ????

Cast of type 'SEL' (aka 'SEL *') to 'uintptr_t' (aka 'unsigned long') is deprecated; use sel_getName instead

Xcode 4.6 DPs are showing that this cast is invalid. They suggest using sel_getName instead.

/Users/tonyarnold/Documents/Client Work/someapp/Vendor/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa/libextobjc/extobjc/EXTRuntimeExtensions.m:735:55: Cast of type 'SEL' (aka 'SEL *') to 'uintptr_t' (aka 'unsigned long') is deprecated; use sel_getName instead
/Users/tonyarnold/Documents/Client Work/someapp/Vendor/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa/libextobjc/extobjc/EXTRuntimeExtensions.m:762:55: Cast of type 'SEL' (aka 'SEL *') to 'uintptr_t' (aka 'unsigned long') is deprecated; use sel_getName instead

This is well outside my current experience, otherwise I'd have a whack at fixing the issue myself — sorry Justin!

synthesizeLazyAssociation

Hey,

Since 99% of our category properties are lazy, it is necessary we find an easy way to get libextobj to work nicely with this.

First naive idea is to synthesizeAssociation an internal property that is initialized the first time the external property gets called, by adding a nil check. But... Why not take it one step further?

Looking at the EXTSynthesize code, it doesn't seem hard at all to add a callback for initializing the property in the getter block. That's how the synthesizeLazyAssociation idea was born, and I would guess that I'll just have to add one more block parameter that returns an id type.

I'll start implementing this on our fork, anyway, since we need it, but any better ideas are appreciated or if you think this is a good addition, will be happy to clean it up and submit a PR.

Thanks!

pedantic keywordify question

I used the keywordify macro in another repo. Seeing that, @mattmassicotte observed that

@try{} @finally {}

might be ... "lighter weight" than

@try{} @catch(...) {}

It's certainly fewer characters, and less to explain (i.e. the ... syntax). Thoughts?

Error with AspectImplementation

Although I've declared a protocol by @aspect() macro, but I will get null when invoking objc_getProtocol() in the @aspectimplementation macro, and get a run time error when using @aspectimplementation.

*** Assertion failure in BOOL ext_loadSpecialProtocol(Protocol *__strong, void (^__strong)(__unsafe_unretained Class))()

After I change the line in the aspectimplementation macro

interface NAME ## _AspectContainer : NSObject {} \

to this line with an explicit protocol declaration

interface NAME ## _AspectContainer : NSObject <NAME> {} \

everything is fine.

So I think the compiler might not compiler or include the non-using protocol.

fix in EXTRuntimeExtensions.m

When you are pruning your class list in EXTRuntimeExtensions.m, you are moving too little memory, with the result that the last class gets lost. Here is a fix. The only change is in one argument of the memmove line.

        if (!keep) {
            if (--classCount > i) {
                memmove(allClasses + i, allClasses + i + 1, (classCount - i) * sizeof(*allClasses));
            }
            continue;
        }

Here is the same code with some NSLogs you can use to convince yourself that the change is needed. Without the change, you will see that the next to last class appears twice, and the last one is missing.

        if (!keep) {
            if (--classCount > i) {
                NSLog(@"throwing out class %@", NSStringFromClass(class));

                memmove(allClasses + i, allClasses + i + 1, (classCount - i) * sizeof(*allClasses));
                for (int q = 0; q < classCount; q++) {
                    Class class = allClasses[q];
                    NSString* classString = NSStringFromClass(class);
                    NSLog(@"remaining %@ of %d", classString, classCount);
                }
            }

            continue;
        }

Bug in cache for `ext_globalMethodSignatureForSelector`

I suspect this cache is a bug:

NSMethodSignature *ext_globalMethodSignatureForSelector (SEL aSelector) {
    // set up a simplistic cache to avoid repeatedly scouring every class in the
    // runtime
    static const size_t selectorCacheLength = 1 << 8;
    static const uintptr_t selectorCacheMask = (selectorCacheLength - 1);
    static void * volatile selectorCache[selectorCacheLength];

    const char *cachedType = selectorCache[(uintptr_t)(void *)aSelector & selectorCacheMask];
    if (cachedType) {
        return [NSMethodSignature signatureWithObjCTypes:cachedType];
    }

    //...

Looks like a hash table based on the lowest-order byte of the selector pointer. Unfortunately, there's no way to tell when there is a collision. When there is, this function will probably be returning the wrong signature.

I ran a naïve test, running through every class, every instance method, gisted here. A collision occurred after 8 methods.

xctest[64093:303] first collision with -[NSMenuItemHighlightColor setStroke] and -[NSMenuItemHighlightColor colorWithAlphaComponent:]
xctest[64093:303] tested 2834 classes, 56004 methods, 50268 collisions, first collision @ method 8

I have a minimal fix in mind, probably caching a struct of {SEL sel, char *types}, which lets you detect collisions and overwrite the old value. I'll probably fix it myself for my own purposes. I can put together a pull request, if it's not fixed already by then.

Suggestion about metamacro_argcount

Hello.

Please, consider basing metamacro_argcount on the solution proposed here so it could properly count zero-arguments presence.

I see the next comment there states "This uses a nonstandard GCC extension." but I can't evaluate myself if it is really a no-no for Objective-C world so I decided to write you about this solution to know if it can be included into libextobjc.

Thanks.

Question regarding @weakify and @strongify

I've just started using the @weakify and @strongify macros from EXTScope.h and have a quick question about their proper usage.

If used with a method such as UIView's animateWithDuration:animations:completion: do I need to use @strongify in each block I reference the variable passed to @weakify?

For instance, is this the correct usage:

NSTimeInterval duration = 0.125;
@weakify(self);
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
    @strongify(self);
    [self.flashView setAlpha:1.0f];
} completion:^(BOOL finished) {
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        @strongify(self);
        [self.flashView setAlpha:0.0f];
    } completion:^(BOOL finished) {
        @strongify(self);
        self.flashing = NO;
    }];
}];

Problem building OSX with latest commit (63a83ae401)

Using Xcode 4.6.3. iOS will build, but OSX (32 & 64) fails. I get this:

In file included from /Users/clay/dev/libextobjc/extobjc/EXTAspect.m:13:
libffi/ios/include/ffi.h:2:10: error: 'ffi_armv7.h' file not found with <angled> include; use "quotes" instead
#include <ffi_armv7.h>
         ^~~~~~~~~~~~~
         "ffi_armv7.h"

and then assorted ffi related errors. Just for a sanity check:

$ git submodule status
 6f6e3af400de470057e61ee36c73e2bb6c91ab0b Configuration (0.4-6-g6f6e3af)
 8ed37a45f62904ea01eef9d686984f0c878b9b43 libffi (v3.0.10-120-g8ed37a4)

Not much of a stretch to wonder whether it's mistakenly picking up the iOS headers somehow. Anomalies noted:

  • iOS header search paths are specified in the .xcconfig file. OSX ones are spec'd in the build configs.
  • iOS header search path is recursive (but not for the tests), OS X is not
  • I get a bad feeling about the ./** for user header search paths

Can workaround by dropping EXTAspect.m from build proper, and EXTAspectTest.m from the tests.

@checkselector generate incorrect code if there is a space inside selector

Clang format accidentally formatted my code from

@checkselector(self, dispatchEvent:)

to

@checkselector(self, dispatchEvent :) //an extra space has been inserted before colon

@checkselector can't handle the extra space and it's expanded to incorrect code:

@(((void)(__objc_no && ((void)[self dispatchEvent : (0)], __objc_no)), "dispatchEvent :")).ext_toSelector 

The selector got at runtime is dispatchEvent :, which will be unrecognized by self as it contains a space.

Try / Finally in Macros

I wanted to know the reason for the try {} finally {} in each macro. It seems somewhat arbitrary but I am not a macro expert.

Unit Tests fail without ARC

Works fine if you set (at least) the test bundle target to use ARC.. but that's not how the project is set on a fresh pull. This was building for OS X.

Macro sugar mostly for logging

My apology for opening as an issue (I miss DMs). I use metamacros a ton since learning RAC and have a few derivatives for code generation and especially logging I wondered could fit conceptually here? metamacros are lower level and everything else higher so otherwise I'll nix your namespace and push them elsewhere for personal reuse. And thx this, RAC, and Mantle are hands down my fave projects supporting iOS.

Suggestions about EXTNil

EXTNil is good. Here are the suggestions:

1. Using generic names for using EXTNil

Adding those two lines in the bottom of EXTNil.h header to use EXTNil more intuitive.

@compatibility_alias NilObj EXTNil;
#define nilObj [EXTNil null]

Using nilObj to present a null object, and NilObj to present the null object class. Those names are more generic.

And adding the following category implementation to help print the nilObj info.

@implementation EXTNil (Description)
- (NSString*)description {return @"<nilObj>";}
@end

And the output:

NSLog(@"%@", nil);
NSLog(@"%@", [NSNull null]);
NSLog(@"%@", nilObj);

==> (null)
==> <null>    
==> <nilObj>

2. Adding a universal null object test method.

There is no universal function/method to determine whether an object is nil, NSNull, or EXTNil. You can see the comparison below:

When TestObject is nil NSNull EXTNil
! testObject YES NO NO
TestObject == nil YES NO NO
testObject == [NSNull null] NO YES NO
[testObject isEqual:nil] NO NO YES
[testObject isEqual:[NSNull null]] NO YES YES

My suggestion is adding a universal method -isNotNilObj to test an object:

// in EXTNil.h
@interface NSObject (NullObjectDesignPattern)
- (BOOL) isNotNilObj;
@end

// in EXTNil.m
@implementation NSObject (NullObjectDesignPattern)
- (BOOL) isNotNilObj {return YES;}
@end

@implementation NSNull (NullObjectDesignPattern)
- (BOOL) isNotNilObj {return NO;}
@end

@implementation EXTNil (NullObjectDesignPattern)
- (BOOL) isNotNilObj {return NO;}
- (NSString*)description {return @"<nilObj>";}
@end

Now, every object will return YES when receiving an -isNotNilObj message except the receiver is nil, NSNull, or EXTNil.

TestObject nil NSNull EXTNil
[testObject isNotNilObj] NO NO NO
![testObject isNotNilObj] YES YES YES

3. Make [NSNull null] return nilObj (EXTNil)

To make an old project can be compatible using nilObj, you may provide a convenient way to make [NSNull null] return nilObj (e.g. method swizzling).

4. Convenient converting between nil and nilObj

Sometime you need to check whether an object is not nil before adding it into an NSArray, 'NSDictionary', or other object.

if (obj) {
    [array addObject:obj];
}

But with the following macros,

// return nilObj if the obj is nil; otherwise, return the obj itself.
#define nilObjify(obj) ([obj isNotNilObj]? obj:nilObj)
// return nil if the obj is nilObj; otherwise, return the obj itself.
#define nilify(obj) ([obj isNotNilObj]? obj:nil)

you can now write the code in one line:

[array addObject: nilObjify(obj)];

Problem in EXTAspect with NSManagedObjects from CoreData

In CoreData entity (child of NSManagedObject) work little bit tricky. Doc says:

NSManagedObject uses dynamic class generation to support the Objective-C 2 
properties feature (see “Objective-C 2 Support”) by automatically creating a subclass of 
your class appropriate for your entity. This is also typically transparent to you, however 
whereas NSManagedObject’s class method returns your class, the Objective-C 
function object_getClass returns the dynamically-generated class.

This leads to the fact that in

- (void)adviseSetters:(void (^)(void))body property:(NSString *)property

property == nil

Tag new version for "post removal of experimental branch"

Hey @jspahrsummers -- first, just want to say: libextobjc is fantastic! Using concrete protocols has been a time and sanity saver in a fairly complex project I'm working on. My issue isn't your fault at all, but more so a CocoaPods specific use case issue.

For CocoaPods sake, could you please tag a version (even it's clearly a dev label version, today's data, "0.3.99", or whathaveyou) that represents a snapshot post removal of the experimental extensions? One of those (Aspect, IIRC) uses libffi, which is all kinds of broken when drawn in with libextobjc 0.3 via CocoaPods. Post your removal of the experimental extensions, this issue simply goes away, as the dependent code is gone.

I tried forking and tagging my own repo at your current repo HEAD, but that wasn't accepted for the CocoaPods spec upstream, since CocoaPods demands to have explicitly tagged versions for releases, and prefers not to use forks (rightly so). That saga is noted here: CocoaPods/Specs#7766

A minute of your time to make the tag would be greatly appreciated. I have the new podspec ready to go! ;-)

Cheers!

@weakify(self) optimized out(?) in Release builds xcode 6 beta 6

Hello everybody,

I have a @weakify(self); inside my viewDidLoad. Later in the code I have a call to

   doCompleted:^{
     @strongify(self);
     [self syncCompletedSuccess:dbPath voicemails:voicemailsPath];
   }]

I've noticed that in Release builds weak_self just after creation is nil as it is nil inside of the do block.

Printing description of self_weak_:
(ATSyncController *const) self_weak_ = <no location, value may have been optimized out>

I will try to replace my doCompleted with a subscribeCompleted in order to clean up a bit, but it doesn't see how it can be the cause of the problem.

Do you have an idea on how this could be fixed ?

Thank you

@weakify/@strongify in nested blocks

Hi,

I have been looking through the library documentation in order to find some guidance on how to use @weakify and @strongify in nested blocks, but cannot find any. For example, which is correct?

1. @weakify once and subsequently @strongify in blocks

- (void) test {
      @weakify(self)
      id block = ^{
        @strongify(self);
        [self doSomething];
        nestedBlock = ^{
          @strongify(self);
          [self doSomethingElse];
        }();
      };
      block();
}

2. Alternate @weakify/@strongify

- (void) test {
      @weakify(self)
      id block = ^{
        @strongify(self);
        [self doSomething];
        @weakify(self)         // @weakify again before the nested block?
        nestedBlock = ^{
          @strongify(self);
          [self doSomethingElse];
        }();
      };
      block();
}

Would be great to get some guidance on what is appropriate here.

Many thanks,

J

Documentation Feedback

It looks like the code is extremely well documented (in headerdoc/doxygen format no less) in the headers themselves. Would love to see docs available as HTML without having to dig into each header.

Ideally I'd love to see the README you have now sprinkled with examples. I think that would let me know at a glance what you're trying to achieve and what my use case would be for each technique/trick you're providing.

How would you do ADT Serialization?

This could be more of a question than an issue. It'd be nice to have an official voice on this.

ADTs are super useful. However, do they enjoy the same level of serialisation support as normal Obj-C objects? (How) could ADTs be automatically serialized and deserialized to and from a blob?

e.g. will ADT objects work with JSONKit

I'm looking for something analogous to the Binary typeclass in Haskell (see here).

Thanks!

SafeCategory finds the conflict when implementing both class method and instance method using the same selector name.

Implementing both class method and instance method using the same selector name will cause conflict:

@safecategory(NSObject, HelloWorld)
+ (void) helloWorld{
    NSLog(@"helloWorld");
}
- (void) helloWorld{
    NSLog(@"helloWorld");
}
@end

On console:

ERROR: Could not add class method +helloWorld to NSObject (a method by the same name already exists)
ERROR: Failed to fully load safe category NSObject (HelloWorld)

And I found the instance method in the safe category will actually add the implementation into both the class selector and the instance selector:

// Only implement the -helloWorld in the safe category
@safecategory(NSObject, HelloWorld)
- (void) helloWorld{
    NSLog(@"helloWorld");
}
@end

Now, both +helloWorld and -helloWorld will print the helloWorld string on the console.

By the way, my suggestion is changing the keyword safecategory to SafeCategoryImplementation to specify you are writing in the @implementation...@end block.

`@strongify(…)`: Declaration shadows a local variable

I'm seeing the following error in Xcode 4.next (Apple LLVM Compiler 4.2) in an iOS project. Anytime I use @strongify(…) in my code, LLVM is warning that "Declaration shadows a local variable".

I can turn the warning off obviously, but is anyone else experiencing this? Am I doing something wrong in my project config?

Idea: compile-time validation for type equivalence between two keypaths

@keypath allows for compile-time validation of the existence of a given a keypath. It would also be useful to validate a keypath's type.

The practical application for this is observing one keypath, and once it changes, using its value to set another keypath. For example, I'm working on something now that observes properties of a view controller, and forwards the values of those properties to their respective destinations on the view.

(As an aside, I hate to be that guy that posts feature requests on an open source project, but the README specifically instructed to post ideas like this.)

ext_globalMethodSignatureForSelector crash issue in iPAD||iOS8

Hi,
Not entirely sure whether ext_globalMethodSignatureForSelector method is actual culprit, but from crash log I could at least zeroed in where it started from. Please find below the crash log... appreciate for any help!!

Thread : Crashed: NSOperationQueue 0x15c9c440 :: NSOperation 0x15cc9030
0  JavaScriptCore                 0x2cc93776 WTFCrash + 53
1  JavaScriptCore                 0x2cc93725 WTFPrintBacktrace + 128
2  WebCore                        0x370f7459 WebCore::FloatingPointEnvironment::propagateMainThreadEnvironment()
3  WebCore                        0x36d44957 StartWebThread() + 462
4  libsystem_pthread.dylib        0x39a3bdab __pthread_once_handler + 50
5  libsystem_platform.dylib       0x39a32ebb _os_once + 42
6  libsystem_pthread.dylib        0x39a39f73 pthread_once + 50
7  WebKitLegacy                   0x3783b4ed +[WebView(WebPrivate) enableWebThread] + 276
8  WebKitLegacy                   0x3783aa07 WebKitInitialize + 70
9  UIKit                          0x2eeeb161 ___UIApplicationLoadWebKit_block_invoke + 152
10 libdispatch.dylib              0x398bb40f _dispatch_client_callout + 22
11 libdispatch.dylib              0x398c89e7 dispatch_once_f$VARIANT$mp + 62
12 UIKit                          0x2edd76fb +[UIWebDocumentView initialize] + 42
13 libobjc.A.dylib                0x3935b4c5 _class_initialize + 536
14 libobjc.A.dylib                0x39361047 lookUpImpOrForward + 254
15 libobjc.A.dylib                0x39360f3f _class_lookupMethodAndLoadCache3 + 34
16 libobjc.A.dylib                0x393671f9 _objc_msgSend_uncached + 24
17 libobjc.A.dylib                0x39359e93 _class_resolveMethod + 90
18 libobjc.A.dylib                0x3936108b lookUpImpOrForward + 322
19 libobjc.A.dylib                0x39360e43 class_getInstanceMethod + 42
20 CoreFoundation                 0x2b7e92f7 __methodDescriptionForSelector + 202
21 CoreFoundation                 0x2b7693e5 +[NSObject(NSObject) methodSignatureForSelector:] + 24
22 FooBar for iPad                0x005994df ext_globalMethodSignatureForSelector
23 FooBar for iPad                0x005cd9f5 -[EXTNil methodSignatureForSelector:]
24 CoreFoundation                 0x2b7e6ee7 ___forwarding___ + 166
25 CoreFoundation                 0x2b718938 _CF_forwarding_prep_0 + 24
26 FooBar for iPad                0x002dabe7 -[FooBarWeeklyAdRequest baseURLParameters:] (FooBarWeeklyAdRequest.m:46)
27 FooBar for iPad                0x002db6e5 -[FooBarGenericCoverImageRequestPrivate init] (FooBarWeeklyAdGetPromotionImageRequest.m:133)
28 FooBar for iPad                0x002db695 __66-[FooBarWeeklyAdGetPromotionImageRequest initWithStoreSlug:width:]_block_invoke (FooBarWeeklyAdGetPromotionImageRequest.m:114)
29 FooBar for iPad                0x00560d99 -[FoorBarOperationChainer start] (FooBarOperationChainer.m:76)
30 Foundation                     0x2c4e2a57 __NSOQSchedule_f + 186
31 libdispatch.dylib              0x398c55d9 _dispatch_queue_drain$VARIANT$mp + 948
32 libdispatch.dylib              0x398c50a9 _dispatch_queue_invoke$VARIANT$mp + 84
33 libdispatch.dylib              0x398c70d3 _dispatch_root_queue_drain + 330
34 libdispatch.dylib              0x398c81fb _dispatch_worker_thread3 + 106
35 libsystem_pthread.dylib        0x39a38e25 _pthread_wqthread + 668

Suggestions about `@onExit`

Suggest that using a block style following the onExit macro:

@onExit ^{

};

instead of the original style:

@onExit {

};

This would make users more conscious about they are writing in a block scope. :)

logic error -- quicksort does not work on partially ordered sets

Hey, thanks for the project, I love concrete protocols and use them a lot. However, you do have a logic error -- quicksort needs a totally ordered set to work. So if protocols a and b are not related (neither inherits from the other), you still need to give them an ordering, or your quicksort can fail, resulting in an incorrect inheritance hierarchy, as other, related protocols never get tested against each other in the quicksort. Fortunately the fix is easy -- just return a consistent total ordering. here is one way to do it:

int ext_compareConcreteProtocolLoadPriority (const void *a, const void *b) {
if (a == b)
return 0;

const EXTConcreteProtocol *protoA = a;
const EXTConcreteProtocol *protoB = b;

// if A conforms to B, A should come first
if (protocol_conformsToProtocol(protoA->protocol, protoB->protocol))
    return -1;
// if B conforms to A, B should come first
else if (protocol_conformsToProtocol(protoB->protocol, protoA->protocol))
    return 1;
else if ((NSInteger)a<(NSInteger)b)
    return -1;
else
    return 1;

}

William Jockusch

libextobjc's onExit macro conflicts with Cocos2D library

Would it be possible to rename the onExit macro to something a little less common? Say onExitScope or something similar? At present it conflicts with at least the Cocos2D library which has an onExit method that is heavily used in Cocos2D applications.

EXTSynthesize objective-c++ compatibility

Hello. I'm trying to use @synthesizeAssociation in my objective-c++ code and I have a problems. There are two compiler errors when I'm building the code. First is about using restrict keyword in ext_synthesizeBlockProperty function declaration. Seems like clang in c++ mode doesn't recognize this keyword(maybe it's undefined in libc++?) but it knows about __restrict. How about replace all restrict keywords with __restrict? It also works for pure C99(+ Objective-C)

Second one is about initialization of global static variable ext_methodInjectionOverwriteBehaviorMask at EXTRuntimeExtensions.h — there is a type mismatch there — on the left side is a const ext_methodInjectionBehavior and on another — int, so compiler(again, in c++ mode) warns us about it in a strong manner :) As hotfix it can be fixed by explicit C-style cast from int to ext_methodInjectionBehavior but it seems a not good decision. What do you think about it?

idea: Abstract class and methods

In order to mark a class as abstract, I have to add the unavailable attribute to the +[Class alloc] and +[Class new] methods. I wonder if there is a better, faster way to achieve this with libextobjc?

As for methods, I simply add an exception or assertion.

idea: assert logic flow

Hi!

Being a super lazy programmer, I have never taken the time to write unit test for my code. I do, however, inline asserts everywhere I can manage to add them.

Now, I would like to assert the logical flow of the code. For example, I would like to have an assert that fails if the code reaches viewDidLoad before init.

I have implemented it using a singleton tracker with a key, but I was wondering if it was possible to do some low level stuff to make that work more elegantly.

Thanks!

EXTSynthesize generate methods that damage neighboring generated properties

I'm trying to use EXTSyntesize in my project and found a very strange behaviour that breaks my code. I have two properties on a class category and do @synthesizeAssociation to them. Then I set some value to first property and using it. Then I set some another value to second property and first property becomes equal to this another value! It's not exactly what I expected. Test to reproduce:

@interface NSObject (EXTSynthesizeTest)
@property (nonatomic, strong) id value1;
@property (nonatomic, strong) id value2;
@end

@implementation NSObject (EXTSynthesizeTest)
@synthesizeAssociation(NSObject, value1);
@synthesizeAssociation(NSObject, value2);
@end

@implementation EXTSynthesizeTest
- (void)testMultiplePropertiesUsage {
    NSObject *owner = [[NSObject alloc] init];

    id value1  = [@"foobar" mutableCopy];
    id value2  = [@"bardoo" mutableCopy];

    owner.value1 = value1;
    STAssertEqualObjects(owner.value1, value1, @"");

    owner.value2 = value2;
    STAssertEqualObjects(owner.value2, value2, @"");

    STAssertEqualObjects(owner.value1, value1, @""); // Failed  
    STAssertEqualObjects(owner.value1, value2, @""); // Passed
}
@end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.