I'm trying to get the email address of a contact and the type of the email address (work/home). This is the code I've written
//Assume that 'personRef' of type ABRecordRef is available
....
ABMultiValueRef emailRef = ABRecordCopyValue(personRef, kABPersonEmailProperty);
NSMutableArray *emailAddresses = nil, *emailAddressLabels = nil;
int ctr = ABMultiValueGetCount(emailRef);
if(ctr!=0) {
emailAddresses = [[NSMutableArray alloc]init];
emailAddressLabels = [[NSMutableArray alloc]init];
for(int i=0; i<ctr; i++) {
NSString *eId = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(emailRef, i);
[emailAddresses addObject:eId];
CFStringRef label = ABMultiValueCopyLabelAtIndex (emailRef, i);
if(label!=NULL) {
NSString *eType = (__bridge_transfer NSString*)ABAddressBookCopyLocalizedLabel(label);
if([eType isEqualToString:#""]) {
[emailAddressLabels addObject:#"Email"];
} else {
[emailAddressLabels addObject:eType];
}
CFRelease(label);
}
}
}
The code crashes at CFRelease(label), but to prevent memory leak, I should be doing it. When I try the following
NSString *eType = (__bridge_transfer NSString*) ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex (emailRef, i));
I get the following warning from ARC
1. Call to function 'ABMultiValueCopyLabelAtIndex' returns a Core Foundation object with a +1 retain count
2. Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1
Now the question I have is, How to do a nesting __bridge_transfer call?
NSString *eType = (__bridge_transfer NSString*)
ABAddressBookCopyLocalizedLabel(
ABMultiValueCopyLabelAtIndex (emailRef, i) /* <-- this object is leaked */
);
This code is invalid because you leak the Label here (which I realise is your point I guess?).
You should run that code under the Instruments NSZombie instrument, it will trace all the retain/releases and you'll have a clue what's going on, because frankly, looking at the code, I don't see why it's wrong.
Related
So for some project i'm working with Xamarin.Forms.
Since one area is just unbearably slow with Xamarin.Forms i've used a CustomRenderer to solve one particular area where a list is involved.
After getting back to the project and upgrading packages, i've suddenly got the weirdest bug.
I am setting "1234" to an EditText, and the EditText.Text Property is suddenly "49505152" - the string is converted to its ascii equivalent.
Is this a known issue? Does anyone know how to fix it?
The cause of the issue was that my EditText had an InputFilter applied and that after updating a package suddenly another code path of FilterFormatted was executed.
public ICharSequence FilterFormatted(ICharSequence source, int start, int end, ISpanned dest, int dstart, int dend)
{
var startSection = dest.SubSequenceFormatted(0, dstart);
var insert = source.SubSequenceFormatted(start, end);
var endSection = dest.SubSequenceFormatted(dstart, dest.Length());
var merged = $"{startSection}{insert}{endSection}";
if (ValidationRegex.IsMatch(merged) && InputRangeCheck(merged, CultureInfo.InvariantCulture))
{
StringBuilder sb = new StringBuilder(end - start);
for (int i = start; i < end; i++)
{
char c = source.CharAt(i);
sb.Append(c);
}
if (source is ISpanned) {
SpannableString sp = new SpannableString(sb);
TextUtils.CopySpansFrom((ISpanned)source, start, sb.Length(), null, sp, 0);
return sp;
} else {
// AFTER UPDATE THIS PATH WAS ENTERED UNLIKE BEFORE
return sb;
}
}
else
{
return new SpannableString(string.Empty);
}
}
I'm trying to run this code in iOS 8 but I'm getting a bad access error in the method called, this runs ok in iOS 7. Does anyone has a clue about this?
-(double) calcularColumna:(int ) anio :(int) mes :(NSString * ) columna {
NSInvocation * invocation = [selectores objectForKey:columna];
if(!invocation){
NSString * metodo = [NSString stringWithFormat:#"fondo%#:anio:mes:",columna];
SEL selector = NSSelectorFromString(metodo);
if( ![self respondsToSelector:selector]) {
return -1;
}
invocation = [NSInvocation invocationWithMethodSignature:[[self class] instanceMethodSignatureForSelector:selector]];
invocation.selector = selector;
invocation.target = self;
[invocation setArgument:(__bridge void *)(self.valoresEntrada) atIndex:2];
[selectores setObject:invocation forKey:columna];
}
double valor = 0;
[invocation setArgument:&anio atIndex:3];
[invocation setArgument:&mes atIndex:4];
[invocation invoke];
[invocation getReturnValue:&valor];
/* }else {
valor = -1;
}*/
return valor;
}
Thanks for your comments.
[invocation setArgument:(__bridge void *)(self.valoresEntrada) atIndex:2];
is wrong. You need to pass a pointer to the value being passed. Something like
// I don't know the type of self.valoresEntrada, but you can use the type directly
typeof(self.valoresEntrada) temp = self.valoresEntrada;
[invocation setArgument:&temp atIndex:2];
Also, if you are going to store the invocation in a collection for use after the scope where it's created, you need to do [invocation retainArguments];
p.s. [[self class] instanceMethodSignatureForSelector:selector] can be written as [self methodSignatureForSelector:selector]
p.p.s. If the method signature is known and fixed at compile-time, you can use objc_msgSend directly, if you are brave.
As per the Title, How to delete mulitple QIntValidator pointer Object created locally.I am stuck with an issue of memory leak.
I have a function as below:
void ABC::setTableDataItems(QStringList headerData)
{
int row = headerData.size();
int column = 0;
if (_txtLineEdit != NULL) {
delete _txtLineEdit;
_txtLineEdit = 0;
}
for (int i = 0; i < row ; i++)
{
_txtLineEdit = new QLineEdit();
_txtLineEdit->setMaxLength(_pktStruct[i].ItemDataLength);
_txtLineEdit->setText(headerData.at(i));
_pktStruct[i].currentLine = _txtLineEdit;
QString regExp = "[01]{1,";
regExp.append(QString("%1").arg(_pktStruct[i].ItemDataLength)).append("}");
long maxDigit = getMaxValueForDigit( _pktStruct[i].ItemDataLength );
QIntValidator* decValidator = new QIntValidator( 0, maxDigit, _txtLineEdit );
QRegExpValidator* binValidator = new QRegExpValidator(QRegExp(regExp),_txtLineEdit);
switch (_pktStruct[i].ItemDataType)
{
case DATA_TYPE_ASCII:
break;
case DATA_TYPE_HEX:
break;
case DATA_TYPE_NUM:
_txtLineEdit->setValidator(decValidator);
break;
case DATA_TYPE_BINARY:
_txtLineEdit->setValidator(binValidator);
break;
case DATA_TYPE_MAX:
break;
}
ui->pcusim_cmd_task_tableWidget->setCellWidget(i, column, _txtLineEdit);
connect(_txtLineEdit, SIGNAL(textChanged(QString)), this, SLOT(on_pcusim_cmd_task_tableWidget_linedit_cellChanged(QString)));
}
}
In above function, I need to delete all multiple QIntValidator created dynamically (inside For Loop ) every time before the loop when the above function is called.
Don't know the way. Please give some suggestions / idea to proceed further ??
Thanks in advance
Why don't you do
QValidator* pValidator = NULL;
switch (_pktStruct[i].ItemDataType)
{
case DATA_TYPE_NUM:
// create the proper int validator here
// ...
pValidator = new QIntValidator(0, maxDigit, _txtLineEdit);
break;
case DATA_TYPE_BINARY:
// create the proper regexp validator here
// ...
pValidator = new QRegExpValidator(QRegExp(regExp),_txtLineEdit);
break;
}
_txtLineEdit->setValidator(pValidator);
That way you don't create validators that are not used.
Since you pass _txtLineEdit as parent on construction of validators, they will be deleted when their parent QLineEdit object is destroyed.
By the way, setCellWidget() takes ownership of the widget, so you don't need to delete _txtLineEdit; (assuming this is the one you passed to it, you should have created a list of them in this case)
I have direct show filter which takes an input and process it and give the result to outputpin.
I want to write this filter output data to a file...And i want to do it in its filter class.So i want to get the output pin buffer data.
Shortly how to reach final data of outputpin in its filter? How can i do it?
Not: The output pin is derived from CBaseOutputPin.This is an open source filter it "magically" :-) put wright data to its output pin which i can not figure out how yet...
Update:
Here is the siutuation:
Media Source ----> GFilter ----> FileWriter
I have source code of GFilter... I have no source code of FileWriter...What i want to make is make GFilter write its own data...I debug GFilter get some insight how its transform data but my attemp to write this data result with wrong data... So i deceide for now how to simply get data at its output pin...
Update[2]
In Filter outputpin somwhere the filter writer pass the file writer pin to IStreamPtr variable...Everthing seems to written to a variable m_pIStream which is type of [IStreamPtr]
GFilterOutput::CompleteConnect(IPin *pReceivePin)
{
// make sure that this is the file writer, supporting
// IStream, or we will not be able to write out the metadata
// at stop time
// m_pIStream is IStreamPtr type
m_pIStream = pReceivePin;
if (m_pIStream == NULL)
{
return E_NOINTERFACE;
}
return CBaseOutputPin::CompleteConnect(pReceivePin);
}
...
GFilterOutput::Replace(LONGLONG pos, const BYTE* pBuffer, long cBytes)
{
//OutputDebugStringA("DEBUG: Now at MuxOutput Replace");
// all media content is written when the graph is running,
// using IMemInputPin. On stop (during our stop, but after the
// file writer has stopped), we switch to IStream for the metadata.
// The in-memory index is updated after a successful call to this function, so
// any data not written on completion of Stop will not be in the index.
CAutoLock lock(&m_csWrite);
HRESULT hr = S_OK;
if (m_bUseIStream)
{
IStreamPtr pStream = GetConnected();
if (m_pIStream == NULL)
{
hr = E_NOINTERFACE;
} else {
LARGE_INTEGER liTo;
liTo.QuadPart = pos;
ULARGE_INTEGER uliUnused;
hr = m_pIStream->Seek(liTo, STREAM_SEEK_SET, &uliUnused);
if (SUCCEEDED(hr))
{
ULONG cActual;
hr = m_pIStream->Write(pBuffer, cBytes, &cActual);
if (SUCCEEDED(hr) && ((long)cActual != cBytes))
{
hr = E_FAIL;
}
}
}
} else {
// where the buffer boundaries lie is not important in this
// case, so break writes up into the buffers.
while (cBytes && (hr == S_OK))
{
IMediaSamplePtr pSample;
hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
if (SUCCEEDED(hr))
{
long cThis = min(pSample->GetSize(), cBytes);
BYTE* pDest;
pSample->GetPointer(&pDest);
CopyMemory(pDest, pBuffer, cThis);
pSample->SetActualDataLength(cThis);
// time stamps indicate file position in bytes
LONGLONG tStart = pos;
LONGLONG tEnd = pos + cThis;
pSample->SetTime(&tStart, &tEnd);
hr = Deliver(pSample);
if (SUCCEEDED(hr))
{
pBuffer += cThis;
cBytes -= cThis;
pos += cThis;
}
}
}
}
return hr;
}
You have full source code, step it through with debugger until you reach the point where your filter calls IPin::Receive of the peer downstream filter, update/override code there and you have full control as for writing data into file etc.
Im working on an iOS app where I need to store and retrieve from an SQLite DB, a representation of a NSString that has subscripts. I can create a NSString at compile time with a constant:
#"Br\u2082_CCl\u2084"
\u2082 is a 2 subscript, \u2084 is a 4 subscript. What im storing in the SQLite db is:
"Br\u2082_CCl\u2084"
But what I can not figure out how to do, is reconvert that back into an NSString. The data comes back from the db as a char * "Br\\u2082_CCl\\u2084" Stripping out the extra slash has made no difference in my feeble experiments. I need a way get that back into an NSString - Thanks!
You need one of the NSString stringWithCString class methods or the corresponding initWithCString instance methods.
I solved the problem like this - error checking removed for clarity -
the unicode string comes into the parameter stringEncoded from the db like:
"MgBr\u2082_CH\u2082Cl\u2082"
+(NSString *)decodeUnicodeBytes:(char *)stringEncoded {
unsigned int unicodeValue;
char *p, buff[5];
NSMutableString *theString;
NSString *hexString;
NSScanner *pScanner;
theString = [[[NSMutableString alloc] init] autorelease];
p = stringEncoded;
buff[4] = 0x00;
while (*p != 0x00) {
if (*p == '\\') {
p++;
if (*p == 'u') {
memmove(buff, ++p, 4);
hexString = [NSString stringWithUTF8String:buff];
pScanner = [NSScanner scannerWithString: hexString];
[pScanner scanHexInt: &unicodeValue];
[theString appendFormat:#"%C", unicodeValue];
p += 4;
continue;
}
}
[theString appendFormat:#"%c", *p];
p++;
}
return [NSString stringWithString:theString];
}