Действительно ли возможно сравнить два блока Objective C содержанием?

float pi = 3.14;
float (^piSquare)(void) = ^(void){ return pi * pi; };
float (^piSquare2)(void) = ^(void){ return pi * pi; };

[piSquare isEqualTo: piSquare2]; // -> want it to behave like -isEqualToString...
18
задан niton 22 April 2015 в 00:02
поделиться

3 ответа

Чтобы расширить ответ Лорана.

Блок - это комбинация реализации и данных. Чтобы два блока были равны, они должны иметь одинаковую реализацию и захватывать одни и те же данные. Таким образом, сравнение требует сравнения как реализации, так и данных.

Казалось бы, сравнение реализации будет несложным. На самом деле это не из-за того, как работает оптимизатор компилятора.

Хотя сравнение простых данных довольно просто, блоки могут захватывать объекты, в том числе объекты C ++ (которые могут когда-нибудь работать), и при сравнении может или не может потребоваться это во внимание. Наивная реализация просто сравнила бы записанное содержимое на уровне байтов.Однако может возникнуть желание проверить равенство объектов с помощью компараторов уровня объекта.

Затем возникает проблема переменных __block. Сам по себе блок фактически не имеет никаких метаданных, связанных с захваченными переменными __block, поскольку они не нужны для выполнения требований указанных переменных. Таким образом, сравнение не могло сравнивать значения __block без значительного изменения кодогенератора компилятора.

Все это говорит о том, что в настоящее время невозможно сравнивать блоки, и обрисовывать некоторые причины этого. Если вы считаете, что это будет полезно, сообщите об ошибке через http://bugreport.apple.com/ и укажите вариант использования.

26
ответ дан 30 November 2019 в 06:54
поделиться

Вы не можете использовать его, так как сертификат SSL связан с доменом www.mywebsite.com , если вы не делаете немного хитрости.

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

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

-121--4407536-

Вот мои результаты для cython

slow_xor   0.456888198853
faster_xor 0.400228977203
cython_xor 0.232881069183
cython_xor_vectorised 0.171468019485

Векторизации в cython бритья о 25% от цикла for на моем компьютере, Однако более половины времени тратится на построение python последовательности ( return оператор) - Я не думаю, что дополнительной копии можно избежать (юридически), так как массив может содержать нулевые байты.

Нелегальным способом было бы прохождение в строке Python и ее изменение на месте и удвоение скорости функции.

xor.py

from time import time
from os import urandom
from numpy import frombuffer,bitwise_xor,byte,uint64
import pyximport; pyximport.install()
import xor_

def slow_xor(aa,bb):
    a=frombuffer(aa,dtype=byte)
    b=frombuffer(bb,dtype=byte)
    c=bitwise_xor(a,b)
    r=c.tostring()
    return r

def faster_xor(aa,bb):
    a=frombuffer(aa,dtype=uint64)
    b=frombuffer(bb,dtype=uint64)
    c=bitwise_xor(a,b)
    r=c.tostring()
    return r

aa=urandom(2**20)
bb=urandom(2**20)

def test_it():
    t=time()
    for x in xrange(100):
        slow_xor(aa,bb)
    print "slow_xor  ",time()-t
    t=time()
    for x in xrange(100):
        faster_xor(aa,bb)
    print "faster_xor",time()-t
    t=time()
    for x in xrange(100):
        xor_.cython_xor(aa,bb)
    print "cython_xor",time()-t
    t=time()
    for x in xrange(100):
        xor_.cython_xor_vectorised(aa,bb)
    print "cython_xor_vectorised",time()-t

if __name__=="__main__":
    test_it()

xor _ .pyx

cdef char c[1048576]
def cython_xor(char *a,char *b):
    cdef int i
    for i in range(1048576):
        c[i]=a[i]^b[i]
    return c[:1048576]

def cython_xor_vectorised(char *a,char *b):
    cdef int i
    for i in range(131094):
        (<unsigned long long *>c)[i]=(<unsigned long long *>a)[i]^(<unsigned long long *>b)[i]
    return c[:1048576]
-121--1038629-

Отложите в сторону вопросы реализации компилятора и дизайна языка, то, что вы просите, является явно неопровержимым (если только вы не заботитесь только об обнаружении 100% идентичных программ). Решение о том, вычисляют ли две программы одну и ту же функцию, эквивалентно решению задачи остановки. Это классическое следствие Теоремы Райса: Любое «интересное» свойство машин Тьюринга неопределиваемо, где «интересное» просто означает, что оно верно для одних машин и ложно для других.

Просто для удовольствия, вот доказательство. Предположим, что мы можем создать функцию, чтобы решить, эквивалентны ли два блока, называемые EQ (b1, b2). Теперь мы используем эту функцию для решения проблемы остановки. Мы создаем новую функцию HALT (M, I), которая говорит нам, если машина Тьюринга M остановится на входе I нравится так:

BOOL HALT(M,I) {
  return EQ(
    ^(int) {return 0;},
    ^(int) {M(I); return 0;}
  );
}

Если M (I) останавливается, то блоки эквивалентны, так что HALT (M, I) возвращает YES. Если M (I) не останавливается, то блоки не эквивалентны, поэтому HALT (M, I) возвращает NO. Обратите внимание, что нам не нужно выполнять блоки - наша гипотетическая функция EQ может вычислить их эквивалентность, просто посмотрев на них.

Сейчас мы решили проблему остановки, которая, как мы знаем, невозможна. Поэтому EQ не может существовать.

13
ответ дан 30 November 2019 в 06:54
поделиться

Я не думаю, что это возможно. Блоки могут быть примерно видны как расширенные функции (с доступом к глобальным или локальным переменным). Так же, как вы не можете сравнить контент функций, вы не можете сравнить содержимое блоков.

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

4
ответ дан 30 November 2019 в 06:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: