It doesn't work without the NSLog()... Why?

2009-04-29 Thread Тимофей Даньшин

Hello.
It's a very funny thing. And i do hope i am not bonkers. But the  
following code works fine until i delete the line with NSLog().  
In the latter case it just returns an empty array. Are there any sane  
reasons why that can happen?


- (NSArray *) selectWordsBeginningWith:(NSString *) s {

	NSLog(@We do call SelectWordsBeginningWith); //- here is that  
line.

NSString *searchString = [NSString stringWithFormat:@%...@%@, s, 
@%%];
NSMutableArray *mutableRet = [[NSMutableArray alloc]init];

	[self intoArray:mutableRet addItemFromTable:@english  
usingStatement:readEnglish andSearchString:searchString];
	[self intoArray:mutableRet addItemFromTable:@russian  
usingStatement:readRussian andSearchString:searchString];


sqlite3_reset(readEnglish);
sqlite3_reset(readRussian);
NSArray *ret = [mutableRet copy];
//  NSLog(@The number of items to be returned is: %i, [ret count]);
[mutableRet release];
return ret;
}

Thank you in advance,
Timofey.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Kyle Sluder
2009/4/29 Тимофей Даньшин ok5.ad...@gmail.com:
 It's a very funny thing. And i do hope i am not bonkers. But the following
 code works fine until i delete the line with NSLog(). In the latter
 case it just returns an empty array. Are there any sane reasons why that can
 happen?

No, there is no sane reason for this behavior.  Though I remember
reading a story very recently somewhere in which someone had this
exact issue, and it had to do with the way that NSLog left the stack
when it completed.

You probably have a memory management or other issue somewhere,
perhaps in wherever is calling -selectWordsBeginningWith:.  But you
haven't posted nearly enough code to make even an educated guess.  You
need to post the code for
-intoArray:addItemFromTable:usingStatement:andSearchString: at the
very least.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Graham Cox


On 29/04/2009, at 10:05 PM, Тимофей Даньшин wrote:


NSArray *ret = [mutableRet copy];
//  NSLog(@The number of items to be returned is: %i, [ret count]);
[mutableRet release];
return ret;



I don't see why your NSLog line should cause a problem, but your  
memory management at the end of the function is wrong, so may have a  
bearing on it.


Why copy mutableRet when you just release it anyway? Instead, just  
return it with an autorelease:


return [mutableRet autorelease];

There is no need to copy a mutable array just so you can return it as  
a non-mutable array - it is an array and its mutability is invisible  
to the client of this code. As it stands you're leaking the copy  
because it is never released.


--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Тимофей Даньшин
Why copy mutableRet when you just release it anyway? Instead, just  
return it with an autorelease:
I do that because i return an immutable array. I always try to return  
the types i promise to return in the declaration :)


To Kyle:
I looked at the - 
intoArray:addItemFromTable:usingStatement:andSearchString:, but i  
failed to find anything bad in there. Here is the code:


- (void) intoArray:(NSMutableArray *)mutableRet addItemFromTable: 
(NSString *)table usingStatement:(sqlite3_stmt *)statement  
andSearchString:(NSString *) searchString {


	sqlite3_bind_text(statement, 1, [searchString  
cStringUsingEncoding:NSUTF8StringEncoding], -1, SQLITE_TRANSIENT);


while (sqlite3_step(statement) == SQLITE_ROW) {
		NSString *s = [NSString stringWithUTF8String:(char *)  
sqlite3_column_text(statement, 0)];

int wid = sqlite3_column_int(statement, 1);
		[mutableRet addObject:[WordIdAndDatabase makeWithId:wid word:s  
andDatabaseName:table]];

}
}

And here is some more detailed description of the problem. The thing  
is that i have a class called Database which is responsible for  
communicating with my database. The Database class is controlled by a  
DatabaseManager, which is a singleton... Any object in my application  
wanting to get anything from the db calls the [DatabaseManager  
sharedManager] and calls the methods it needs to call.


As I may have mentioned before, the app I am writing is a dictionary.  
The user interface has an NSTableView and an NSTextField. As the user  
types a searchword into the textfield, the app creates new  
NSOperations that select the words beginning with the chars the user  
has typed, from the database, and then i show them in the table view.  
Again, all the interactions with the db are executed via the  
DatabaseManager.


When the user hits enter or clicks on a cell with a word in it, we  
select that word with the equivalent from the db and display that in a  
different window.


And the thing is that when the NSLog line we talked above is not  
there, the -selectWordsBeginningWith: method works fine only until the  
user presses Enter or clicks a cell, i.e. until we get another class  
connect to the database.


Again, with NSLog in place, it all works fine no mater how many  
translations you open...


I would be really grateful for any hints to what the cause might be.




On Apr 29, 2009, at 4:32 PM, Graham Cox wrote:



On 29/04/2009, at 10:05 PM, Тимофей Даньшин wrote:


NSArray *ret = [mutableRet copy];
//  NSLog(@The number of items to be returned is: %i, [ret count]);
[mutableRet release];
return ret;



I don't see why your NSLog line should cause a problem, but your  
memory management at the end of the function is wrong, so may have a  
bearing on it.


Why copy mutableRet when you just release it anyway? Instead, just  
return it with an autorelease:


return [mutableRet autorelease];

There is no need to copy a mutable array just so you can return it  
as a non-mutable array - it is an array and its mutability is  
invisible to the client of this code. As it stands you're leaking  
the copy because it is never released.


--Graham




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Michael Ash
2009/4/29 Тимофей Даньшин ok5.ad...@gmail.com:
 Hello.
 It's a very funny thing. And i do hope i am not bonkers. But the following
 code works fine until i delete the line with NSLog(). In the latter
 case it just returns an empty array. Are there any sane reasons why that can
 happen?

Does it break if you delete the NSLog and run it in the debugger? If
so, step through the code until you find the place where it's going
wrong, and fix it.

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Graham Cox


On 29/04/2009, at 10:48 PM, Тимофей Даньшин wrote:

Why copy mutableRet when you just release it anyway? Instead, just  
return it with an autorelease:
I do that because i return an immutable array. I always try to  
return the types i promise to return in the declaration :)





Even so, you're leaking the copy because it should be returned  
autoreleased, as per correct memory management rules. The fact that  
you're not doing this here suggests that memory management may be  
flaky elsewhere, as Kyle suggested.


However, returning the mutable array when your method promises a non- 
mutable array is perfectly OK. NSMutableArray is an NSArray and  
therefore the method has fulfilled its contract. If the client code  
then tests its class and discovers that it is in fact mutable after  
all, and mutates it, then the client code is the bad guy here. All the  
copy does is waste time, and serves no purpose. Still, if it makes you  
feel better...




Note that:

- (NSArray *) selectWordsBeginningWith:(NSString *) s;

Does not include the word new, alloc, copy or mutableCopy and  
therefore the caller does not own the array returned.





--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: It doesn't work without the NSLog()... Why?

2009-04-29 Thread Graham Cox


On 29/04/2009, at 10:48 PM, Тимофей Даньшин wrote:

- (void) intoArray:(NSMutableArray *)mutableRet addItemFromTable: 
(NSString *)table usingStatement:(sqlite3_stmt *)statement  
andSearchString:(NSString *) searchString {





Also, I don't mean to pick on your code (there's nothing obviously  
wrong with what you've posted so far apart from the leak I mentioned  
already), but as a matter of style, this way of designing methods is a  
bit strange. In the interests of being as self-contained and clean as  
possible, I'd rearrange this method something like this:


- (NSArray*) itemsFromTableWithName:(NSString*) table sqlStatement: 
(sqlite3_stmt*) statement searchString:(NSString*) searchString;


This way the method stands alone with a fully defined and self- 
documenting purpose that can be called by anyone without having first  
to create a NSMutableArray to pass into it. If they want to accumulate  
the results into a further array, then fine, do that; if they don't,  
they haven't had to create an array just to keep your code happy.  
There are also fewer failure modes, because this code is responsible  
for creating the returned array, and not relying on the client to do  
so. It's also easier for the client to detect success or failure,  
because a returned empty or nil array could mean something. In your  
case, the client would have to examine the contents of the array  
before and after to figure out if anything had actually happened.


This design is widely seen throughout the Cocoa frameworks, whereas  
the intoArray: type thing you have I don't think I've ever seen. It's  
usually a good plan to follow the approaches used in the frameworks,  
they are for good reason.


--Graham


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com