Блоки на самом деле являются как типами C, так и типами Objective-C. Вы можете связать объекты с ними, используя API-интерфейсы среды выполнения objc, вы можете поместить их в коллекции ObjC и т. Д., И все же они все еще действительны в программах на языке C Это аккуратная хитрая работа по совместимости со стороны компилятора и пользователей среды выполнения :)

ел бы добавить функции, создав категорию для блоков Objective-C.

__block int (^aBlock)(int) = ^int( int n ){
    if( n <= 1 ) return n;
    return aBlock( n - 1 ) + aBlock( n - 2 );
};

Вместо того, чтобы просто позволить нормальный[aBlock copy], [aBlock retain], [aBlock release], [aBlock autorelease], Я мог бы сделать что-то вроде:

[aBlock mapTo:anArray];

Возможная категория

@interface UnknownBlockClass (map)

- (NSArray *)mapTo:(NSArray *)array_;

@end
 mipadi19 янв. 2011 г., 14:31
@JeremyP: Да, но (а) это только на 10.6, и (б) я реализую остальную часть протокола коллекций Smalltalk, а также некоторые функциональные возможности из класса Ruby Enumerable.
 JeremyP19 янв. 2011 г., 10:17
@mipadi: знаете ли вы о существующей карте, например, о функциональности, например-enumerateObjectsUsingBlock: а такжеvalurForKey:
 mipadi19 янв. 2011 г., 06:59
Кстати, я начал работу над библиотекой Objective-C, которая добавляет карту и связанные с ней функцииNSArray а такжеNSSet: github.com/mdippery/collections

Ответы на вопрос(5)

вы не можете добавить категорию в класс, который вы не видите, но поскольку блоки являются подклассамиNSBlock добавив:

@interface NSBlock : NSObject
@end

Теперь вы можете «увидеть»NSBlock и добавьте категорию, например:

@interface NSBlock (map)
- (NSArray *)mapTo:(NSArray *)array;
@end

@implementation NSBlock (map)
- (NSArray *)mapTo:(NSArray *)array
{
    ...
}
@end

Тем не менее, вероятно, не самая лучшая вещь в коде, который фактически используется в производстве ...

WRONG: A block winds up being an instance of type __NSGlobalBlock__, as seen in the     
following snippet:

int i = 0;
id o = [class self];

void (^aBlock)(void) = ^(void) {

    [o setValue:0];

    NSLog(@"Hello world %d", i);
};

// prints "type = __NSGlobalBlock__" 

// Now it prints __NSStackBlock__ 
// and when moved into HEAP prints __NSMallocBlock__

NSLog(@"type = %@", [aBlock class]);

NSGlobalBlockmsgstr "если в области нет захваченных переменных, в противном случае он будет создан в STACK и при копировании переместит блок в HEAP, и каждая ссылка будет сохранена!

а не объект Objective C. Вы можете вызвать [aBlock copy], но это вызывает функцию C block_copy (), а не метод копирования nsobject. Таким образом, тип __block является типом C, и поэтому вы не можете добавлять категории.

Исправление: __ block - это идентификатор в компиляторе C, а не typedef.

Я не уверен, что это достигнет того, что вы думаете, на самом деле, на самом деле, я даже не совсем уверен, что он делает:

__block int (^aBlock)(int) = ^int( int n ){
if( n <= 1 ) return n;
return fib( n - 1 ) + fib( n - 2 );
};

идентификатор __block сообщает компилятору, что переменная должна быть изменяемой в ссылочных блоках и должна сохраняться, если какой-либо ссылочный блок копируется в кучу. Что меня смущает в вашем коде, так это то, что __block обычно используется для переноса переменной, а не самого блока.

 Rich19 янв. 2011 г., 06:57
теперь это имеет больше смысла.
 Kendall Hopkins19 янв. 2011 г., 06:50
__block позволяет мне пройтиaBlock в блок. Я переименовал блок и забыл переименоватьfib Рекомендации.
 Catfish_Man15 янв. 2013 г., 01:46
Блоки на самом деле являются как типами C, так и типами Objective-C. Вы можете связать объекты с ними, используя API-интерфейсы среды выполнения objc, вы можете поместить их в коллекции ObjC и т. Д., И все же они все еще действительны в программах на языке C Это аккуратная хитрая работа по совместимости со стороны компилятора и пользователей среды выполнения :)
Решение Вопроса

потому что вы не можете создать категорию для класса, который вы не видите.

Тем не мение...

Что я собираюсь сказать вам, вы должны строго использовать как упражнение в обучении, иНИКОГДА В ЛЮБОЙ ВИДЕ НАСТРОЙКИНекоторый самоанализ во время выполнения выявляет некоторую интересную информацию. Есть ряд классов, которые содержат слово «Блок». Некоторые из них выглядят многообещающе:__NSStackBlock, __NSMallocBlock, __NSAutoBlock, а такжеNSBlock.Еще один самоанализ показывает, что многообещающие классы наследуют отNSBlock

Таким образом, похоже, что любой блок будет неким экземпляром или подклассомNSBlock.

Вы можете создать метод для объекта, например так:

@implementation Foo
- (void) doFoo {
  //do something awesome with self, a block
  //however, you can't do "self()".  
  //You'll have to cast it to a block-type variable and use that
}
@end

Затем во время выполнения вы можете переместить этот метод вNSBlock класс:

Method m = class_getInstanceMethod([Foo class], @selector(doFoo));
IMP doFoo = method_getImplementation(m);
const char *type = method_getTypeEncoding(m);
Class nsblock = NSClassFromString(@"NSBlock");
class_addMethod(nsblock, @selector(doFoo), doFoo, type);

После этого блоки должны реагировать наdoFoo сообщение.

ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК И ТОЛЬКО ДЛЯ ЭКСПЕРИМЕНТА.
 Dave DeLong23 июн. 2011 г., 19:52
@ Джонатан, я не уверенгарантированныйСамоанализ показывает, что частныйNSBlock классявляется подклассNSObject, Так что это работает для возни, но (как я уже говорил в посте) использовать его в любых условиях производства глупо.
 emp22 июн. 2011 г., 19:24
Чужой может быть, но не страшно. Это очень распространено в Smalltalk, который вдохновил Objective-C. В Smalltalk нет управляющего синтаксиса. Поэтому оператор if будет выглядеть как [^ BOOL {return a> 1} ifTrue: ^ {...}] (за исключением того, что в Smalltalk намного чище: [a> 1] ifTrue: [...].)
 Jonathan Sterling23 июн. 2011 г., 19:46
Но (поправьте меня, если я ошибаюсь), блочные объекты на самом деле не гарантируются отNSObject
 Jonathan Sterling03 апр. 2011 г., 08:45
Хлоп! :) Другой вариант - просто сделать категорию наNSObjectи обещаю использовать его только на блоках ... В любом случае, это немного страшно, и я бы предпочел безопасность явного[Utility somethingWithBlock:block] а также[arr map:block] над скудостью[block doSomething] а также[block map:arr]...

Блок оказывается экземпляром типа__NSGlobalBlock__, как видно из следующего фрагмента:

    void (^aBlock)(void) = ^(void) {
        NSLog(@"Hello world");
    };

    // prints "type = __NSGlobalBlock__"
    NSLog(@"type = %@", [aBlock class]);

Чтобы создать категорию класса, компилятор должен видеть оригинал@interface объявление класса. Я не могу найти декларацию для__NSGlobalBlock__ и, вероятно, не зря.

эта статья а такжеэта статья содержать некоторую полезную информацию о реализации блоков.

К исходной точке, почему бы просто не сделать категориюNSArray для тебяmapTo метод? Кажется, это лучшее место для такой функциональности.

обновленный

Скажем вамМожно добавить категорию к объекту Block. Как бы вы вызвали блок из метода категории? Насколько я понимаю, единственный способ вызвать блок через() оператор (например,aBlock()). Я не думаю, что есть способ узнать из объекта Block количество и типы параметров. Итак, какие аргументы вы бы передать в вызов блока?

Я не рекомендую вам делать это, но следующие работы ...

@interface NSObject (BlockExtension)
- (void)foo;
@end

@implementation NSObject (BlockExtension)
- (void)foo
{
    // not sure how else to determine if self is a Block since neither
    // __NSGlobalBlock__ nor any of its superclasses (except NSObject) 
    // are accessible to the compiler
    if ([[[self class] description] isEqual:@"__NSGlobalBlock__"])
    {
        NSLog(@"foo");
        // now what?
        // can't call self(), it doesn't compile
        // how else can I invoke this block?
    }
}
@end

...

void (^aBlock)(void) = ^(void) {
    NSLog(@"Hello world");
};

// prints "foo"
[aBlock foo];
 Kendall Hopkins19 янв. 2011 г., 07:00
Я просто использовалmapTo В качестве примера. Я могу придумать несколько приложений для такой категории: состав функций, карри и т. Д.
 bbum19 янв. 2011 г., 18:51
Умно, да, но опасно. Нет никакой гарантии, что различные классы NSBlock будут неотъемлемо присуще NSObject ...
 Dave DeLong19 янв. 2011 г., 07:44
+1 категория наNSObject это умный способ сделать это.

Ваш ответ на вопрос