вы пропускаете ваше заявление return
, поэтому ваши function
возвращают undefined
const isEmpty = value => {
//you are not returning anything
return value === undefined ||
typeof value === "undefined" ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
};
const data = {};
data.handle = !isEmpty(data.handle) ? data.handle : "";
console.log("data.handle is still undefined: " + typeof data.handle);
if (typeof data.handle === "undefined") {
data.handle = "";
console.log("empty string yes!!!");
}
ClassOne *pointer = [[ClassOne alloc]init];
Переменная pointer
указатель на объект класса ClassOne. Это это присвоило значение недавно созданного объекта.
ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
*foo
и *foo2
объекты класса ClassTwo
. Только foo
присвоен недавно созданный объект. foo2
может указать на что-либо, таким образом, небезопасно использовать его прежде, чем присвоить ему значение.
foo2 = [foo add: pointer];
foo2
присвоен значение: Я предполагаю что add:
сообщение класса ClassTwo
создает объект (подпись метода должна быть -(ClassTwo*)add:(ClassOne*);
)
[foo release];
Объект, которым указывают foo
больше не необходим.
foo = foo2;
Переменная foo
присвоен значение foo2
: обе точки к тому же объекту.
[pointer release];
Объект, которым указывают pointer
больше не необходим.
[foo release];
Объект, которым указывают foo
(и также foo2
) больше не необходим.
Ничего себе, Спасибо всем за большие ответы!
Я предполагаю то, что я действительно предназначен, ссылка на объект и не указатель. Тем не менее, я предполагающий добавленный , *foo2
находится в той же памяти как нечто. Также foo2 освобожден память формы в то же время, что и нечто. Я все еще имею намного больше для склонности, но однажды за один раз!
С Какао Objective C мы работаем с полуавтоматическим управлением памятью подсчета ссылок. При выделении памяти для объекта, сохранении объекта или вызове a copy
метод на объекте, сохранить количество (подсчет ссылок) увеличивает 1. При вызове release
на объекте это постепенно уменьшает сохранить количество одним. При вызове autorelease
на объекте, release
будет назван на объекте в какой-то момент в будущем (во время основного цикла выполнения, когда ни один из Вашего собственного кода не выполняется, таким образом, это не вытянет ссылку из-под Вас, поскольку Вы пытаетесь использовать его). Когда сохранить количество достигает 0, объект может быть освобожден.
В целом, если Вы звоните retain
на объекте Вы предупреждаете о своем интересе к нему, и Вы ответственны за то, что сделали a release
или autorelease
звоните в какой-то момент, когда Вы больше не будете интересоваться объектом. Аналогично, если Вы звоните alloc
или a copy
метод на объекте, Вы предупредили о своем интересе к объекту и должны соответствовать ему a release
или autorelease
где-нибудь по линии.
Эта ссылка в значительной степени касается инструкций использование Apple (и необходимо использовать) для управления памятью: Простые правила для управления памятью в Какао
Давайте пройдем строку кода с методической точностью:
ClassOne *pointer = [[ClassOne alloc]init];
pointer
точки к недавно выделенному объекту ClassOne, с сохранить количеством 1, так как мы назвали выделение на нем. Мы несем ответственность звонить release
или autorelease
на pointer
в какой-то момент в будущем.
ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
foo
точки к недавно выделенному объекту ClassTwo, с сохранить количеством 1, так как мы назвали выделение на нем. Мы несем ответственность звонить release
или autorelease
на foo
в какой-то момент в будущем.
foo2
ни на что не указывает в особенности прямо сейчас. Не безопасно использовать.
foo2 = [foo add: pointer];
pointer
был добавлен к foo
(независимо от того, что это означает; мы не знаем реализацию). foo
возможно, звонил retain
на pointer
сигнализировать о его интересе к нему, и добавило его как поле, или это, возможно, добавило pointer
к набору (в этом случае это - обязанность набора звонить retain
на нем, когда объект добавляется, и release
когда объект удален). В любом случае это не влияет на наш блок кода, таким образом, мы не заботимся о том, что продолжается под капотом
Ссылка, возвращенная этим методом, могла бы быть pointer
самостоятельно, или это могла бы быть автовыпущенная копия pointer
; у нас нет доступа к API или реализации, чтобы сказать нам который.
В любом случае это не наша обязанность звонить release
на этом объекте. Если метод имел copy
на имя, или если мы звонили retain
на возвращенной ссылке (как foo2 = [[foo add:pointer] retain];
), затем сохранить количество было бы увеличено 1, и это будет наша обязанность звонить release
или autorelease
на нем.
[foo release];
Объект, на который ссылаются foo
был выпущен, означание сохранять количество было постепенно уменьшено 1. Для этого примера это соединяется с alloc
звоните мы сделали в строке 2, таким образом, сохранить количество спадет 0, делая foo
имея право быть освобожденным.
В целом, тем не менее, мы не заботимся, был ли объект освобожден или нет; мы просто должны удостовериться, что разделяем на пары любого alloc
, copy
, или retain
вызовы с тем же количеством release
или autorelease
вызовы. Если мы регистрируем интерес к объекту когда-либо, это - наша обязанность выпустить наш интерес, иначе у нас будут утечки памяти.
foo = foo2;
foo
теперь точки к тому же объекту, на который ссылаются foo2
. Помните, мы не звонили alloc
или copy
метод, когда мы добрались foo2
, и при этом мы не регистрировали интерес к нему путем вызова retain
. Так как мы не несем ответственность звонить release
на foo2
, мы не несем ответственность звонить release
на foo
.
[pointer release];
pointer
сохраните количество, был постепенно уменьшен 1. Это, возможно, принесло сохранять количество к 0 или нет, оно зависит от какой foo
сделал с ним, когда мы добавили его. Однако, мы не заботимся; мы закончили нашу ответственность перед pointer
путем вызова release
на нем для соответствия alloc
звоните мы сделали вначале. Хотя pointer
мог бы все еще быть вокруг после этого вызова, мы не можем сделать то предположение, и пытающийся сделать что-либо с объектом, на который ранее ссылается указатель, была бы ошибка (хотя мы могли измениться pointer
указать на что-то еще свободно).
[foo release];
Если автор этого кода следовал конвенциям управления памятью Apple, то это является ненужным. Мы не несем ответственность звонить release
на foo
или foo2
(они указывают на тот же объект, помнят). Это не заставит код повреждаться; вызов чего-либо на a nil
ссылка по существу нет. Однако это может вызвать беспорядок для любого рассматривающего код.
Теперь, автор этого кода, возможно, повредил конвенции управления памятью. Он, возможно, сделал это add
возврат вызова копия pointer
без вызова autorelease
на нем, в этом случае он делает вызывающую сторону ответственной за вызов release
на нем. Это - очень невоспитанность, и если необходимо столкнуться с кодом, который повреждает конвенцию управления памятью, документ, где Вы используете его и как это повреждает конвенцию избежать беспорядка в будущем.
Поскольку Вы не выпустили его. Вы выпускаете ссылки здесь, не освобождая указатели. Это - не совсем то же самое. Когда Вы делаете [выпуск нечто] во второй раз, когда Вы выпускаете ссылку нечто, которую Вы создали при присвоении foo2 нечто.
Для выпуска foo2 ссылки Вам нужно к на самом деле разъединению вызова на той ссылке, не копии ссылки.
Это действительно зависит от какой [foo add:pointer];
делает. Похоже, что это отдает копию foo
и сохранение его. Это - явно плохой дизайн, потому что должно быть очевидно из метода, если возвращенный объект является копией / ссылка. Методы с именованным add:
не должен отдавать копию.
Шаг за шагом:
// this somehow creates a retained copy of foo.
foo2 = [foo add:pointer];
// foo is released and gets destroyed.
[foo release];
// makes foo point to the same object as foo2
// (`foo` has no connection to the former object anymore)
foo = foo2;
// foo (and foo2 as they point to the same object) are released
[foo release];
От Вашего простого примера действительно трудно сказать, что продолжается. Обычно [класс добавьте:] вводят возврат методов пусто, таким образом, они должны повысить предупреждение компилятора, которые 'освобождают значение, не проигнорирован, как это должно быть'.
Таким образом без большего количества информации, немного трудно понять вещи.
Несколько вещей иметь в виду:
можно отправить команды в 'ноль' в objc. Так, если [нечто add:pointer] возвращает ноль, то можно назвать 'выпуск' на всем этом днем без влияния.
retainCount является Вашим другом. Можно назвать его на любом NSObject для наблюдения, сколько объекты содержат на него. Это может также помочь Вам разыскать проблему.
Наконец, находится Сборка "мусора" на?
То, на чем Вы действительно пытаетесь сфокусироваться, - то, как работают указатели. Я думаю, что Вы еще не поняли различия между указателями и объектами.